目录
1.1静态多态
1.2动态多态
1.2.1满足条件
1.2.2动态多态的使用条件
1.3纯虚函数和抽象类
1.3.1纯虚函数
1.3.2抽象类
1.4虚析构/纯虚析构
1.5向上向下类型转换
1.5.1向下类型转换
1.5.2向上类型转换
1.5.3多态中的类型转换
1.6重载重写重定义
1.6.1重载
1.6.1.1函数重载
1.6.1.2运算符重载
1.6.2重写
1.6.3重定义
1.1静态多态
1.2动态多态
注意:静态多态和动态多态的区别在于早绑定或晚绑定
1.2.1满足条件
- 有父子类的继承关系
- 父类中有虚函数
- 子类重写父类中的虚函数
1.2.2动态多态的使用条件
利用父类的指针或引用,指向子类对象
Animal* an = new cat;
1.3纯虚函数和抽象类
1.3.1纯虚函数
//语法
virtual 返回值类型 函数名(参数列表)= 0;
多态中,父类的虚函数通常是没有意义的,主要是调用子类的重写内容,故可以将虚函数改为纯虚函数,就不用写函数的实现体了。
1.3.2抽象类
抽象类:若一个类中存在纯虚函数/纯虚析构,则为抽象类
特点:无法实例化对象
子类必须重写父类中的纯虚函数,不然也属于抽象类
1.4虚析构/纯虚析构
Animal* animal = new Cat("Tom");
animal->speak();
delete animal;
此时,delete只会调用父类的析构函数,不会调用子类的析构函数,导致出现内存泄漏
解决办法:虚析构/纯虚析构
//虚析构
virtual~ 父类析构名() {}
//纯虚析构
virtual~ 父类析构名() = 0;
//类外实现
父类名::~父类名(){}
将父类的析构函数改为虚析构/纯虚析构后,执行父类析构时,就会执行子类析构。
注意:纯虚析构有声明,也有实现,纯虚函数不要实现。
1.5向上向下类型转换
1.5.1向下类型转换
特点:
不安全(子类的大小一般大于等于父类,子类大于父类的部分不安全)
1.5.2向上类型转换
特点:安全
1.5.3多态中的类型转换
此时,转换是安全的,因为分配内存的时候就是按照子类的大小,故将父类指针指向子类指针时,不会有问题。
1.6重载重写重定义
1.6.1重载
1.6.1.1函数重载
条件:
- 函数名称相同
- 同一个作用域
- 参数的个数/类型/顺序不同
1.6.1.2运算符重载
operator运算符
1.6.2重写
重写:在继承关系中,子类重写了父类中的虚函数。
要求:子类中的函数返回值、函数名、参数列表与父类完全一致。
1.6.3重定义
重定义:在继承关系中,子类重新定义父类中相同名称的非虚函数。
发生重定义时,子类中同名的函数会隐藏父类中所有重载的同名函数。