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()函数的时候,调用的是指针所指向的重定义的函数,而不是指向原来基类中的函数。


     总结虚函数:

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






  
目录
相关文章
|
6月前
|
C++
C++一分钟之-虚函数与抽象类
【6月更文挑战第21天】在C++中,虚函数与抽象类是多态的基础,增进类间耦合与灵活性。虚函数实现动态绑定,抽象类定义不可实例化的接口。关键点包括:记得使用`virtual`,避免滥用虚函数,确保派生类实现纯虚函数。抽象类不能直接实例化,派生类必须实现所有纯虚函数。通过实例代码学习和实践,能更好地掌握这些概念以优化代码设计。
51 2
|
2月前
|
编译器 C++
C++入门12——详解多态1
C++入门12——详解多态1
40 2
C++入门12——详解多态1
|
2月前
|
C++
C++入门13——详解多态2
C++入门13——详解多态2
81 1
|
4月前
|
编译器 C++ 索引
C++虚拟成员-虚函数
C++虚拟成员-虚函数
|
4月前
|
存储 编译器 C++
|
5月前
|
存储 编译器 C++
【C++】深度解剖多态(下)
【C++】深度解剖多态(下)
54 1
【C++】深度解剖多态(下)
|
5月前
|
存储 编译器 C++
|
5月前
|
机器学习/深度学习 算法 C++
C++多态崩溃问题之为什么在计算梯度下降时需要除以批次大小(batch size)
C++多态崩溃问题之为什么在计算梯度下降时需要除以批次大小(batch size)
|
5月前
|
Java 编译器 C++
【C++】深度解剖多态(上)
【C++】深度解剖多态(上)
55 2
|
5月前
|
程序员 C++
【C++】揭开C++多态的神秘面纱
【C++】揭开C++多态的神秘面纱