C++:多态之虚函数

简介:             一个面向对象的系统常常要求一组具有相同基本语义的方法能在同一接口下为不同的对象服务,这就是多态性(polymorphism).           通俗的来说,多态就是在一个方法在不同基类的派生类中表现出不同的实现形式。
      

     一个面向对象的系统常常要求一组具有相同基本语义的方法能在同一接口下为不同的对象服务,这就是多态性(polymorphism).

          通俗的来说,多态就是在一个方法在不同基类的派生类中表现出不同的实现形式。比如,定义水果类为基类,苹果,梨,香蕉为派生类,在水果类,苹果,梨,香蕉中都有一个计算蒸发率的成员函数,但是,在苹果,梨,香蕉中,因为他们是不同水果,有不同蒸发率,所以,虽然同样是计算蒸发率,但是计算的方法不同,这种用不同方法计算不同派生类蒸发率的方式就是多态。

      在C++中,多态分为:编译时的多态性和运行时的多态性。其中,编译时的多态性通过重载和模板来实现,其实现的机制为一种静态绑定的机制;而运行时的多态性通过虚函数来实现,其实现的方式为一种动态绑定的方式。


    先来看一种静态绑定机制的多态:

   

#include<iostream>
using namespace std;

class People    //人类
{
public:
	print() {cout<<"我是人类"<<endl;}
};

class Singer:People   //歌手类
{
public:
	print() {cout<<"我是歌手:Jay!"<<endl;}
};

class Programmer:People  //程序猿类
{
public:
	print() {cout<<"我是一个程序猿:Vac!"<<endl;}
};


int main()
{
	People p;
	Singer Jay;   //歌手Jay
	Programmer Vac;  //程序猿Vac

	p.print();

	cout<<endl;

	Jay.print();

	cout<<endl;

	Vac.print();

	cout<<endl;

	return 0;


}

结果如我们所预料的那样:




Singer JayProgrammerVac分别调用本类中定义的print()函数,输出的结果也是我们想要的。但是这种调用是建立在静态绑定机制上的,不具备多态特征。


PS:

  多态调用是借助于指向基类的指针或引用的调用。


下面来看一下用指针访问的情况:


#include<iostream>
using namespace std;

class People    //人类
{
public:
	print() {cout<<"我是人类"<<endl;}
};


class Singer:public People   //歌手类
{
public:
	print() {cout<<"我是歌手:Jay!"<<endl;}
};

class Programmer:public People  //程序猿类
{
public:
	print() {cout<<"我是一个程序猿:Vac!"<<endl;}
};

int main()
{
	People p;
	Singer Jay;   //歌手Jay
	Programmer Vac;  //程序猿Vac

	People * Pp=&p;
	People * PJay=&Jay;
	People * PVac=&Vac;

        Pp->print();
	PJay->print();
	PVac->print();

	return 0;



}


运行时出现如下结果:




这显然不是我们想要得到的,指针所执行的函数都是基类的print()函数,根本没有实现多态。



解决方法:


   


只要在声明基类People的时候,将print()声明为虚函数,则在用指针或引用访问print()函数的时候,调用的是指针所指向的重定义的函数,而不是指向原来基类中的函数。


     总结虚函数:

             指向基类的指针在操作它的多态类对象时,会根据不同的类对象,调用其相应的函数,这个函数就是虚函数






  
目录
相关文章
|
22天前
|
C++
9. C++虚函数与多态
9. C++虚函数与多态
24 0
|
28天前
|
算法 安全 编译器
【C++ 关键字 override】C++ 重写关键字override(强制编译器检查该函数是否覆盖已存在的虚函数)
【C++ 关键字 override】C++ 重写关键字override(强制编译器检查该函数是否覆盖已存在的虚函数)
25 0
|
28天前
|
算法 Java 编译器
【C++ 关键字 virtual 】C++ virtual 关键字(将成员函数声明为虚函数实现多态
【C++ 关键字 virtual 】C++ virtual 关键字(将成员函数声明为虚函数实现多态
25 0
|
22天前
|
编译器 C++
C++之多态
C++之多态
|
24天前
|
存储 程序员 编译器
【C++ 模板类与虚函数】解析C++中的多态与泛型
【C++ 模板类与虚函数】解析C++中的多态与泛型
46 0
|
25天前
|
设计模式 存储 安全
【C++ 基本概念】C++编程三剑客:模板、多态与泛型编程的交织与差异
【C++ 基本概念】C++编程三剑客:模板、多态与泛型编程的交织与差异
102 0
|
25天前
|
存储 安全 算法
【C++ 17 包裹类 泛型容器 std::any】深入理解与应用C++ std::any:从泛型编程到多态设计
【C++ 17 包裹类 泛型容器 std::any】深入理解与应用C++ std::any:从泛型编程到多态设计
47 1
|
28天前
|
存储 算法 编译器
【C++ 模板应用】模板哪些行为属于多态哪些行为属于泛型编程?
【C++ 模板应用】模板哪些行为属于多态哪些行为属于泛型编程?
25 0
|
28天前
|
存储 安全 编译器
【C++ 多态 】深入理解C++的运行时类型信息(RTTI):dynamic_cast和typeid的应用与原理
【C++ 多态 】深入理解C++的运行时类型信息(RTTI):dynamic_cast和typeid的应用与原理
49 1
|
28天前
|
存储 编解码 开发框架
【C++ 多态 】了解 C++ 中的类型擦除和虚拟函数调用
【C++ 多态 】了解 C++ 中的类型擦除和虚拟函数调用
41 1