多态
多态的基本概念
Animal &animal = cat;//父类的指针或者引用 指向子类的对象
- 父类在等号左边
- 如果父类,子类有相同的同名函数,要想实现子类,就要把父类的函数变成虚函数,从而实现地址晚绑定
- 动态多条满足条件
1.有继承关系
2.子类重写父类的虚函数 - 重写要求:函数返回值类型 函数名 参数列表 完全相同
纯虚函数和抽象类
在多态中,通常父类汇中虚函数的实现是毫无意义的,主要都是调用子类重写的内容。
因此可以将虚函数改为纯虚函数。
纯虚函数语法virtual 返回值类型 函数名 (参数列表) = 0; //没有花括号对;
当类中有了纯虚函数,这个类也称为抽象类。
抽象类特点:
- 无法实例化对象(比较抽象的东西)
- 子类必须重写抽象类中的纯虚函数,否则也属于抽象类(目的就是让子类重写纯虚函数)
-
class Base { public: //只要有一个纯虚函数,这个类称为抽象类 //特点;无法实例化对象 virtual void func() = 0;//注意:不要忘掉virtual! //抽象类的子类必须要重写父类中的纯虚函数,否则也属于抽象类 };
Base b;
new Base;
全都错了
虚析构和纯虚析构
虚析构语法;
virtual ~类名(){}
纯虚析构语法:
virtual ~类名() = 0;//声明
类名::~类名(){}
Animal* animal = new Cat("Tom");
animal->speak();
/*
父类的指针在析构的时候,不会调用子类中的析构函数,
导致子类如果有堆区属性,会出现内存的泄漏情况。(子类没析构)
解决:将父类的析构函数改为虚析构
*/
delete animal;
利用虚析构可以解决父类指针释放子类对象不干净 的问题
纯虚析构
虚析构and纯虚析构必须要有代码实现
纯虚函数 不用实现
只要有纯虚析构也是抽象类,不能实例化对象
总结:
- 虚析构或纯虚析构就是用来解决通过父类指针释放子类对象问题
- 如果子类中没有堆区数据,可以不写为虚析构或纯虚析构
- 拥有纯虚析构函数的类也属于抽象类