多态分类:
- 静态多态:编译时多态(函数重载,运算符重载)
- 动态多态:运行时多态
静态联编,动态联编:
-
静态联编:地址早绑定,在编译阶段就绑定好了
-
动态联编:地址晚绑定,在运行阶段就绑定好了
多态就是父类的引用或者指针指向子类对象
多态原理解析:
当父类有了虚函数之后,内部结构就会发生改变,内部多了一个vfptr(virtual function pointer)虚函数表指针,指向vftable(虚函数表)。也就是说父类中的结构变成一个虚函数指针(指针在父类占据的内存中),指向一个虚函数表(表不再父类的占据内存中),表中有父类中的成员函数。子类中进行了继承,会继承父类的虚函数指针,和父类的虚函数表,当创建出自己的对象之后则会指向自己的虚函数表,如果发成了重写,也就是在子类中含有和父类类型,返回值,名字,参数相同的函数则会发生重写,让自己的函数把虚函数表中的函数覆盖掉,但是不会影响父类的函数(还是有点粘,等我在研究研究)。虚函数表的内部是一个数组
纯虚函数和抽象函数:
- 这里纯虚函数在父类和子类中的函数所有属性都一致,只是在父类中没有实现需 要在子类中实现。
那我就在想那如果父类中没有实现那么是不是可以去掉呢?在我尝试之后发现其实并不可以去掉,因为在测试中test()中我们用父类的指针或者引用指向子类的对象,在调用的时候也是父类的指针指向的对象的函数,所以操作的还是父类,只不过在父类中把函数作为了虚函数,所以才调用的是子类同名函数(重写函数),如果父类没有这个函数,那么编译器直接报错父类不包含这个函数的错误。
虚析构和纯虚析构:
虚析构:
纯虚析构:
- 首先了解纯虚函数和纯虚析构的异同,析构函数要和类名相同,那么就不会和纯函数一样重写,因为在父类和子类的函数名字不同,所以纯虚析构像纯函数一样在类中不进行实现但是要进行声明,写法和纯虚函数相同father()=0;,不同点是要在类外进行实现。
还有一个相同点就是纯虚析构也是抽象函数,父类将不能进行实例化。