c++面向对象的三大特征:封装、继承、多态。
多态的分类:
静态多态:函数重载和运算符重载属于静态多态,复用函数名。
动态多态:派生类和虚函数实现运行时多态。
区别:
静态多态的函数地址早绑定 -----编译阶段确定函数地址
动态多态的函数地址晚绑定------运行阶段确定函数地址 virtual void speak( )
动态多态满足条件:
①、有继承关系 void dospeak(Animal& animal)
②、子类重写父类 中的虚函数
动态多态的使用:
父类的指针或者引用指向子类对象
使用动态多态的优点:
代码组织结构清晰
可读性强
利于前期和后期的扩展以及维护
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class AbCal//计算器类
{
public:
virtual int getResult()
{
return 0;
}
int m_A;
int m_B;
};
class AddCal :public AbCal//加法计算器类
{
public:
int getResult()
{
return m_A + m_B;
}
};
void test01()
{
AbCal* abc = new AddCal;//用指针的方式使用动态多态
abc->m_A = 10;
abc->m_B = 20;
cout << abc->getResult() << endl;
delete abc;//释放存在的空间
}
int main()
{
test01();
return 0;
}
纯虚函数和抽象类:
多态中父类中的虚函数的实现是毫无意义的,主要都是调用子类重写的内容,因此可以将虚函数改为纯虚函数
纯虚函数语法:virtual 返回值类型 函数名(参数列表)=0;
当类中有了纯虚函数,这个类也称为抽象类。
抽象类的特点:无法实例化对象;子类必须重写抽象类中的纯虚函数,否则也属于抽象类。
虚析构和纯虚析构
多态使用时,如果子类中有属性开辟到堆区,那么父类指针在释放时无法调用到子类的析构代码,解决方法:将父类中的析构函数改为虚析构或者纯虚析构
虚析构和纯虚析构
共性:可以解决父类指针释放子类对象的问题;都需要有具体的函数实现。
区别:如果是纯虚析构,该类属于抽象类,无法实例化对象
虚析构语法:virtual ~类名(){ }
纯虚析构语法 :virtual ~类名( )=0; 类名::~类名(){ }
总结:1、虚析构或纯虚析构就是用来解决通过父类指针释放子类对象的问题
2、如果子类中没有堆区数据,可以不写为虚析构或纯虚析构
3、拥有纯虚析构函数的类也属于抽象类