问: 可以说一下C++中的多态吗?
答:当一个类继承自另一个类,它可以使用继承来获得基类的属性和方法。在C++中,多态是指子类对象可以被当作父类对象对待的特性。使用父类的指针或引用来引用子类的对象。
C++中的多态是通过虚函数实现的。虚函数是在基类中声明的函数,在派生类中可以被重写。
当使用基类的指针或引用调用虚函数时,根据指针或引用实际所指向的对象的类型,会调用相应的派生类中的函数,而不是基类中的函数。
多态的好处是可以在编译时不确定对象的类型,但在运行时确定调用的函数。这样可以实现基类的通用操作,而不需要关心实际的对象类型。此外,通过多态可以实现动态绑定,从而实现运行时的多态性。
问:如何实现多态的?
答:虚函数表
问:虚函数表是属于类的 还是对象的?
答:虚函数表是针对类的,一个类的所有对象的虚函数表都一样。
虚函数表属于类,类的所有对象共享这个类的虚函数表。
不同对象虚函数表是一样的(虚函数表的第一个函数地址相同);
问:不同对象如何访问虚函数表的?
答:每个对象内部都保存一个指向该类虚函数表的指针vptr,每个对象的vptr的存放地址都不一样,但是都指向同一虚函数表。
C++的编译器保证虚函数表的指针存在于对象实例中最前面的位置,这样通过对象实例的地址得到这张虚函数表,然后就可以遍历其中函数指针,并调用相应的函数。
单继承情况,
1.派生类未重写基类虚函数
虚函数按照其声明顺序放于表中。
父类的虚函数在子类的虚函数前面。
2.派生类重写基类虚函数
虚表中派生类重写的虚函数的地址被放在了基类相应的函数原来的位置 派生类没有覆盖的虚函数延用基类的
多继承情况,
1.派生类无重写基类虚函数
每个基类都有自己的虚函数表
派生类的虚函数地址存依照声明顺序放在第一个基类的虚表最后(这点和单继承无虚函数覆盖相同)
2.派生类重写基类虚函数
虚表中派生类重写的虚函数的地址被放在了基类相应的函数原来的位置
派生类没有重写的虚函数延用基类的
总结
单继承
- 虚表中派生类覆盖的虚函数的地址被放在了基类相应的函数原来的位置
- 派生类没有覆盖的虚函数就延用基类的。同时,虚函数按照其声明顺序放于表中,父类的虚函数在子类的虚函数前面。
多继承
每个基类都有自己的虚函数表
派生类的虚函数地址存依照声明顺序放在第一个基类的虚表最后