C++多态(5)

01 虚函数

  • 在类的定义中,前面有 virtual 关键字的成员函数称为虚函数;
  • virtual 关键字只用在类定义里的函数声明中,写函数体时不用。
class Base 
{
    virtual int Fun() ; // 虚函数
};

int Base::Fun() // virtual 字段不用在函数体时定义
{ }

02 多态的表现形式一

  • 派生类的指针(引用)」可以赋给「基类指针(引用)」;
  • 通过基类指针(引用)调用基类和派生类中的同名「虚函数」时:
  1. 若该指针(引用)指向一个基类的对象,那么被调用是 基类的虚函数;
  2. 若该指针(引用)指向一个派生类的对象,那么被调用 的是派生类的虚函数。

这种机制就叫做“多态”,说白点就是调用哪个虚函数,取决于指针对象指向哪种类型的对象

在非构造函数,非析构函数的成员函数中调用「虚函数」,是多态!!!

构造函数和析构函数中存在多态吗?

在构造函数和析构函数中调用「虚函数」,不是多态。编译时即可确定,调用的函数是自己的类或基类中定义的函数,不会等到运行时才决定调用自己的还是派生类的函数。

「多态」的关键在于通过基类指针或引用调用一个虚函数时,编译时不能确定到底调用的是基类还是派生类的函数,运行时才能确定。

01 虚函数表

每一个有「虚函数」的类(或有虚函数的类的派生类)都有一个「虚函数表」,该类的任何对象中都放着虚函数表的指针。「虚函数表」中列出了该类的「虚函数」地址。

多出来的 8 个字节就是用来放「虚函数表」的地址。

多态的函数调用语句被编译成一系列根据基类指针所指向的(或基类引用所引用的)对象中存放的虚函数表的地址,在虚函数表中查找虚函数地址,并调用虚函数的指令。

「虚函数表的指针」的作用,「虚函数表的指针」指向的是「虚函数表」,「虚函数表」里存放的是类里的「虚函数」地址,那么在调用过程中,就能实现多态的特性。

    // 64位程序指针为8字节
    int * p1 = (int *) & a;
    int * p2 = (int *) pa;

把 A 类的头 8 个字节的「虚函数表指针」存放到 p1 指针和把 B 类的头 8 个字节的「虚函数表指针」存放到 p2 指针

虚析构函数

析构函数是在删除对象或退出程序的时候,自动调用的函数,其目的是做一些资源释放。
那么在多态的情景下,通过基类的指针删除派生类对象时,通常情况下只调用基类的析构函数,这就会存在派生类对象的析构函数没有调用到,存在资源泄露的情况。
步骤:先调用基类析构函数,然后析构基类,派生类的析构无法再调用。

解决办法:把基类的析构函数声明为virtual
•派生类的析构函数可以 virtual 不进行声明;
•通过基类的指针删除派生类对象时,首先调用派生类的析构函数,进行delete等处理后调用基类的析构函数,还是遵循「先构造,后虚构」的规则,先析构基类然后再用派生类析构。

包含纯虚函数的类叫抽象类

•抽象类只能作为基类来派生新类使用,不能创建抽象类的对象
•抽象类的指针和引用可以指向由抽象类派生出来的类的对象

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 一、首先我们先来学习下:《Effect C++》学习------条款05:了解C++默默编写并调用哪些函数。如果你...
    Nrocinu阅读 198评论 0 0
  • 一:基本定义 多态按字面的意思就是多种形态。当类之间存在层次结构,并且类之间是通过继承关联时,就会用到多态。 C+...
    欧阳杰_fac9阅读 1,106评论 0 0
  • 多态 多态性是面向对象程序设计的一个重要特征,能增加程序的灵活性。可以减轻 系统 升级,维护,调试的工作量和复杂度...
    青春猪头少年_阅读 236评论 0 0
  • 多态是面向对象的程序设计的关键技术。多态:调用同一个函数名,可以根据需要但实现不同的功能。多态体现在两个方面,我们...
    随波逐流007阅读 574评论 0 0
  • 什么是多态性? 多态:相同对象收到不同消息或不同对象收到相同消息时产生不同的动作。C++支持两种多态性:编译时多态...
    showaichuan阅读 591评论 0 3