|| 继承适用于存在 相似属性或行为 时
|| 多态适用于存在 同一行为的相似(但行为细节多样) 时
|| c++中,父类和子类间不要求强制类型转换 父类对象作为函数的参数,可以通过父类对象来接收子类对象参数
void test02(Animal &animal) {
animal.speak();
}
Dog dog;
test02(dog);
|| 多态使用中,我们将一个A行为多样化,但使用的都是一个函数名,为了让指定的对象调用其A行为,需要注意函数地址绑定问题
|| 虚函数
使用virtual构造一个 虚函数 可使得该函数的函数地址晚绑定
以上的test02函数涉及到 函数地址早绑定 的问题
在局部函数中调用了对象的成员函数,就会发生函数地址的早绑定
会导致 实际调用行为的对象不符 的错误
虚函数语法:virtual 返回值类型 函数名 (参数列表){} ;
|| 多态实现条件
— 子类“重写”父类的“虚函数”—
父类中:该成员函数设置为虚函数,子类中:重写该成员函数
|| 多态使用
— 父类指针或引用指向子类对象 —
原理:此时animal中的虚函数指针将指向子类对象重写后的虚函数表
(通常可以构建一个普通函数,其参数是父类指针,在调用时实现多态)
Cat cat;
Animal &animal = cat
|| 纯虚函数
在多态中,通常父类中虚函数的实现是毫无意义的,主要都是调用子类重写的内容
因此可以将虚函数改为纯虚函数
纯虚函数语法:virtual 返回值类型 函数名 (参数列表)= 0 ;
|| 虚析构函数
多态使用时,如果子类中有属性开辟到堆区,那么父类指针在释放时无法调用到子类的析构代码
解决方式:将父类中的析构函数改为虚析构或者纯虚析构
虚析构语法:
virtual ~类名(){}
|| 纯虚析构函数
纯虚析构语法:
virtual ~类名() = 0;
类名::~类名(){}
与纯虚函数不同的是,函数=0后,还需要补充其空实现
|| 抽象类
当类中有了纯虚函数(包括纯虚析构函数),这个类则称为抽象类
抽象类特点
*无法实例化对象
*子类必须重写抽象类中的纯虚函数,否则也属于抽象类