知识点:
1.虚函数:父类指针在指向它的多态类对象时,会根据不同类对象调用相应的函数,这个函数就是虚函数
2.虚函数用virtual修饰函数名,定义了虚函数后,可以在子类中对虚函数重新定义。如果没有重新定义,则继承。
3.接口统一,返回类型(除了协变情况)、参数类型、参数个数一致
实现过程:
1.编译器发现一个类中有虚函数时,便为该类生成虚表,虚表各表项为指向对应虚函数的指针。父类虚函数地址在前,子类在后,按照声明顺序。
2.父类指针指向子类对象时,如果子类中函数重写了父类中的函数,则用子类虚函数的地址覆盖掉对应父类虚函数的地址。
3.父类指针调用函数过程:
到父类里,如果发现是虚函数,就到虚函数表里找到对应的虚函数指针。
有覆盖:该指针指向子类函数,调用子类的函数。
无覆盖:调用父类自己的函数。
4.每个对象都会生成一个虚表
纯虚函数:
含有纯虚函数的类称为抽象类,抽象类不能生成对象。纯虚函数不会被调用,主要用来统一管理子类对象。
注意点:
1.构造函数不能是虚函数
构造函数初始化虚表指针vptr,虚函数放在虚表里。调用构造函数时,首先要知道虚表指针vptr。矛盾。
2.内联函数不能是虚函数
3.析构函数默认为虚函数
安全性:
1.用父类指针调用子类中未覆盖父类的成员函数是非法的,但运行时可以通过指针访问虚表来实现该点。
2.如果父类虚函数时private或protected的,也可以通过指针访问虚表来访问non-public虚函数。