c++多态笔记

目录

动态多态满足条件:

动态多态的使用

动态多态原理

总代码

纯虚函数和抽象类

抽象类特点:

虚析构和纯虚析构



静态多态:函数重载、运算符重载。在编译阶段确定函数地址

动态多态:派生类 虚函数。 在运行阶段确定函数地址

动态多态满足条件:

1 、继承关系

2、子类重写父类虚函数

重写(函数返回值名称、函数类型、返回值列表完全相同)

动态多态的使用

父类的指针或引用 指向子类的对象

动态多态原理

 virtual void speak()
    {
        cout<<"animal speak"<<endl;
    }

此时,vfptr(虚函数指针)指向vftable(虚函数表),存放&animal地址

 void speak()
    {
        cout<<"cat speak"<<endl;
    }

当子类重写父类函数时,子类的vfptr(虚函数指针)指向vftable(虚函数表),覆盖掉&animal地址,存放&cat地址

void doSpeak(Animal &animal)
{
    animal.speak();


}
void test01()
{
    Cat cat;
    doSpeak(cat);
 
}

当父类引用指向子类对象时,就会用&cat

总代码

#include <iostream>
using namespace std;
class Animal
{
    public:
    virtual void speak()
    {
        cout<<"animal speak"<<endl;
    }
};
class Cat : public Animal
{
    public:
    void speak()
    {
        cout<<"cat speak"<<endl;
    }
};
void doSpeak(Animal &animal)
{
    animal.speak();


}
void test01()
{
    Cat cat;
    doSpeak(cat);
 
}
int main()
{
    test01();
    return 0;
}

纯虚函数和抽象类

有的父类的虚函数本身没意义,只是为了子类重写。那么可以直接纯虚函数

virtual 返回值类型 函数名(参数) = 0;

virtual int getResult() = 0;

类中有纯虚函数,这个类可以成为抽象类

抽象类特点:

1、不能实例化对象

2、子类必须重写抽象类的纯虚函数,否则也属抽象类

虚析构和纯虚析构

子类中没有堆区数据,可以不写虚析构或纯虚析构

虚析构

父类的指针指向子类的对象,在析构时,只会执行父类的析构,不会执行子类的析构。子类有堆区数据,会内存泄漏。

解决方案:虚析构

在基类的析构函数前加 virtual

语法: virtual ~函数名(){}

 virtual ~Animal()
    {
        cout<<"animal 析构"<<endl;
    }

纯虚析构

语法:virtual ~类名()=0;

         类名::类名(){ }

虚析构是需要实现的,因为要释放父类的指针,换成纯虚析构之后不能在代码段内写实现,应该在类外补一个实现

virtual ~Animal() = 0;

//类外
Animal::~Animal(){}

纯虚析构需要声明也需要实现

有了纯虚析构后,这个类属于抽象类,无法实例化

虚析构和纯虚析构的异同

1、相同:可以解决父类指针释放子类对象,都需要具体的函数实现

2、不同:纯虚析构,该类属于抽象类,无法实例化

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值