10.C++多态
多态分为两类(一般指动态多态)
静态多态:如函数重载和运算符重载
动态多态:派生类和虚函数实现运行时多态
区别在于静态多态的函数地址编译阶段绑定 动态多态的函数地址运行阶段确定
动态多态的条件
1.有继承关系
2.子类重写(完全一致不重载)父类的虚函数 (父类必须加virtual 子类可不加 加到声明即可,此时实现可加可不加)
静态多态的情况
定义一个全局函数
void speak(Animal &animal)
{
animal.speak();
}
cat类继承Animal类时 且两者都有自己的speak函数 子类调用这个全局函数的时候(子类与父类是同一个类型 所以能调用同一个全局函数)
cat t;
speak(t);
此时依然调用的是Animal的speak方法 因为地址编译即分配了
动态多态
若想调用cat的speak函数则 在Animal的函数前加一个virtual关键字 让它变成虚函数 此时会根据类调用自己对应的speak函数
vfptr 虚函数指针
当子类重写父类的虚函数 子类中的虚函数表会替换成子类的虚函数地址
多态的好处:
1.组织结构清晰
2.可读性强
3.对于前期和后期拓展以及维护性高
开闭原则:对扩展进行开发,对修改进行关闭,即尽量不修改代码,而是扩展
纯虚函数和抽象类
在多态中,通常父类中虚函数的实现是毫无意义的,主要都是调用子类重写的内容,因此可将虚函数改为纯虚函数
语法:virtual 返回值类型 函数名(参数列表)=0;
当类中有了纯虚函数,这个类也称为抽象类
抽象类的特点:无法实例化对象,子类必须重写抽象类中的纯虚函数,否则也属于抽象类
虚析构和纯虚析构
多态使用时,如果子类中有属性开辟到堆区,那么父类指针在释放时不会调用到子类的析构代码
解决办法:将父类中的析构函数改为虚析构或者纯虚析构
虚析构语法:virtual ~类名(){}
纯虚析构语法: 声明:virtual ~类名()=0; 实现:类名::~类名(){}
虚析构和纯虚析构的共性:
1.可以解决父类指针释放子类对象
2.都需要有具体的函数实现
虚析构和纯虚析构的区别:
如果是纯虚构,该类属于抽象类,无法实例化对象
更多推荐



所有评论(0)