C++(多态)

今天学习黑马视频中的类的特性之一:多态,根据学习内容进行复习,如下,参考《黑马》——C++核心编程_漏网小鱼的博客-CSDN博客,若侵权,请告知,会删。

  1. 基本语法
  2. 原理剖析
  3. 纯虚函数和抽象类
  4. 虚析构和纯虚析构

多态分类:

静态多态:函数重载和运算符重载等,复用了函数名

动态多态:派生类和虚函数在运行时多态

静态多态为函数地址早绑定,在编译阶段已经确定函数地址

多态多态为函数地址晚绑定,在运行时确定函数地址

1、基本语法

满足条件:

  1. 有继承关系
  2. 子类重写父类中的虚函数

使用方法:

  1. 父类指针或引用指向子类对象
  2. 调用的为父类中的(虚)函数,不同的接口进入

如:Cat cat; Animal &animal =cat(类实例化对象);

Animal *animal=new Cat(类);

实例化的为一个子类(可以直接类实例化如Cat cat,也可以在堆区开辟一块新的内存空间如new Cat),然后用父类指针或者引用指向该子类,然后(可以初始化父类中的成员数据,)调用父类中的(虚)函数即实现多态。相当于后续操作都是针对父类,只是前期将父类指针或引用指向子类,父类中的函数为虚函数,所以会从子类中进入。

个人理解为父类指针或引用指向子类对象,当调用父类中的(虚)函数时,会提供不同的接口,根据下一节知识可知,父类中当有虚函数时,会有一个虚函数指针vfptr,该指针会指向虚函数表vftable,而由于指针的指向为子类,实际运行函数会为子类中重写的父类虚函数,所以当父类指针或引用指向不同的子类对象时,会从不同的接口进入运行。

重写的定义:函数返回值类型,函数名,参数列表完全一致

多态优点:

  • 代码结构清晰
  • 可读性强
  • 利于前期和后期的扩展和维护

提倡多态程序架构,好处多多~

2、原理剖析

当父类中只有函数时,为1个字节,当该函数变为虚函数时,为4个字节,因为存储变成了一个指针。

参考:黑马程序员匠心之作|C++教程从0到1入门编程,学习编程不再难_哔哩哔哩_bilibili

Animal中有一个4个字节的指针vfptr,该指针指向虚函数表, 虚函数表记录的为虚函数函数入口的地址,当子类重写父类的虚函数时,子类中的虚函数表会替换成子类的虚函数地址,当父类的指针或者引用指向子类对象时,本身还是子类对象,如创建的是cat对象,当调用公共接口speak时,会从子类中找函数的实际入口地址即Cat::speak。

开发命令窗口验证:

Animal 类

 Cat类speak函数没有重写时,直接继承Animal类:speak函数继承Animal::speak

 Cat类speak函数重写时:speak变成Cat::speak

 3、纯虚函数和抽象类

多态中父类的虚函数的实现都是无意义的,因为调用的都是子类中的重写的内容,因此将虚函数改为纯虚函数。

语法:virtual 返回值类型 函数名(参数列表)=0;

如:virtual void func() = 0;

当类中有纯虚函数时,该类也称为抽象类。

抽象类特点:

  • 无法实例化对象
  • 子类必须重写抽象类中的纯虚函数,不然子类也属于抽象类

 4、虚析构和纯虚析构

当子类中有属性开辟到堆区时,父类指针在释放时无法调用子类的析构函数,造成内存泄漏,将父类中的析构函数改为虚析构或者纯虚析构可以解决该问题。若子类中无属性开辟到堆区,则不需要父类中的析构函数改为虚析构和纯虚析构。

虚析构和纯虚析构共性:

  • 可以解决父类指针释放子类对象
  • 都需要具体的函数实现

虚析构和纯虚析构个性:

  • 纯虚析构所在的类为抽象类,无法实例化对象

虚析构:virtual ~类名(){}

纯虚析构:virtual ~类名() = 0; 

                  类名::~类名(){}

(纯虚析构函数相当于类内声明,类外实现)

释放子类堆区对象:

~Cat()
{
    cout<<"Cat析构函数调用"<<endl;
    if (this->m_Name!=NULL)
    {
        delete m_Name;
        m_Name=NULL;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值