1. 基本概念
- 面向对象的三大特性:继承,多态,抽象
- 多态性提供Interface与Impl之间的另一层隔离,从而将what与how分离开来.使得程序具有可扩展性.
- c++支持编译时多态(静态多态)和运行时多态(动态多态):
- 编译时多态:运算符重载,函数重载
- 运行时多态:派生类,虚函数
- 两者的区别就是函数地址是早绑定(静态联编)还是晚绑定(动态联编).
- 如果函数的调用,在编译阶段就可以确定函数的调用地址,并产生代码,就是静态多态(编译时多态) ,就是说地址是早绑定的。
- 而如果函数的调用地址不能编译不能在编译期间确定,而需要在运行时才能决定,这就属于晚绑定(动态多态,运行时多态)。
2.多态
开闭原则:对扩展开放,对修改关闭
- 写法:父类的引用或指针指向子类对象
Animal * a;//父类的引用
a=new Cat;//指向子类对象
- 当父类中有了虚函数后,内部结构就发生了改变.父类中会多vfptr这个指针指向虚函数表.
- 子类中会继承vfptr指向vftable.对象创造时构造函数会将虚函数指针指向自己的虚函数表.
- 如果发生了重写,会替换掉虚函数中原有的父类方法,改为子类的方法
3.抽象类和纯虚函数
- 纯虚函数是将父类中的没有实现体的虚函数直接写为:
virtual int getResult()=0;
- 子类继承父类的纯虚函数,必须写实现体,否则由抽象类派生的类也是一个抽象类.
- 如果父类中有了纯虚函数,那这个父类就无法实例化对象了!这时的父类就叫抽象类.
- 抽象类无法实例化对象.
4.虚析构和纯虚析构
普通析构不会调用子类的虚构,导致释放不干净,应该利用虚析构.
- 写法:
virtual ~Animal(){}
- 若没有实现,使用纯虚析构:
virtual ~Animal()=0;//在父类里,要在父类外写实现
Animal::~Animal(){//在父类外
//纯虚析构的实现
}
- 拥有纯虚析构的类也是抽象类,不能实例化.
5. 类型转换
基类开辟的指针空间小,派生类开辟的指针空间会比基类大!
(1)向上类型转换
Animal *animal=new Cat;
->派生类转向基类(多态),安全.
(2)向下类型转换
Cat *cat=new Animal;
->基类转向派生类,不安全.