多态性:操作接口在不同的对象在不同的环境下具有不同的处理方式。
运算符重载和函数重载:静态多态性
虚函数:动态多态性
1.运算符重载:大部分都能重载,左操作数必须为类的对象
- 不能重载的运算符:. .* :: ?:
2.双目运算符重载:
- 函数类型 operator 运算符(形参){......}
3.单目运算符:
- 前置单目运算符++ 无形参
- 后置单目运算符++ 一个形参
4.运算符重载为非成员函数
- 列出所有操作数
5.虚函数:动态绑定,编译时不静态绑定,决定函数调用,运行时确定函数调用
- 内联函数不能做虚函数,因为内联函数是编译时确定运行,是静态绑定
- 静态成员函数不能做虚函数,因为虚函数必须是属于对象的,不属于某个类的,需要用指针去定位指向的对象是谁,然后决定调用哪个函数体
- 构造函数不能是虚函数,析构函数可以是虚函数,因为虚函数相对应一个虚函数指针的虚表,这个指针存在对象的内存空间,而假设构造函数是虚的,那么调用是需要通过对象来调用,而对象还没有实例化,所以内存空间还不存在,因此构造函数不能是虚函数。
- 虚函数的声明只能在类定义的函数声明中,不能在实现时。
virtual关键字:可以不写
6.虚析构函数:在基类指针指向派生类时,若不定义虚析构函数,那么在编译时会根据基类指针类型去调用基类析构函数,而此时派生类资源未被释放,所以需要定义虚析构函数,在编译时不确定调用哪个析构函数,而是在运行时具体确定
7.虚表与动态绑定
运行时如何进行动态绑定的机制?
利用虚表:当前类的各个虚函数的入口地址
8.抽象类:
由于信息不够具体而无法实现,因此定义纯虚函数
- 纯虚函数基类声明,基类没有定义具体操作内容,在派生类中根据需要自己具体定义
- 抽象类:无法定义对象实例化,规范整个类家族的对外接口的统一形式
- virtual 函数类型 函数名(参数表)=0;
9.override 和final 不是关键字
- override:
- 使用情况:基类派生类想要重写的函数没有写一致,导致没有覆盖重写,无法实现多态性
- 显式函数覆盖override
- final:
- 使用情况:类不希望被继承,或者函数不希望被修改