面试题答案
一键面试创建B类对象时虚函数表变化
- 基类虚函数表:基类A有自己的虚函数表,其中包含虚析构函数以及其他可能的虚函数指针。
- 派生类虚函数表:当创建B类对象时,B类会有自己的虚函数表。由于B继承自A,B类虚函数表首先复制A类虚函数表的内容。然后,对于B类重写的虚函数,其虚函数表中对应位置的指针被替换为B类重写版本的函数指针。例如,如果A类有虚函数
virtual void func()
,B类重写了它,那么B类虚函数表中func
函数指针指向B类的func
实现。
销毁B类对象时虚函数表与虚析构函数
- 析构顺序:当销毁B类对象时,首先调用B类的析构函数。由于虚析构函数机制,通过B类对象的虚函数表找到B类析构函数的指针并调用。B类析构函数执行完毕后,由于B继承自A,接着通过虚函数表找到A类的虚析构函数并调用,以此保证正确的析构顺序,先析构派生类部分,再析构基类部分。
- 虚函数表作用:虚函数表在这里起到关键作用,它存储了正确的析构函数指针。通过对象的虚函数表,无论对象实际类型是A还是B,都能准确找到对应的析构函数,保证在多态情况下析构函数的正确调用。
派生类B新增虚函数的影响
- 虚函数表变化:在B类中新增一个虚函数时,B类的虚函数表会在原有基础上增加一个条目,该条目指向新增虚函数的实现。此时B类虚函数表的结构发生变化,比基类A的虚函数表多了一项。
- 虚析构函数调用:虚析构函数的调用机制不受影响,仍然按照先调用B类析构函数,再通过虚函数表调用A类析构函数的顺序进行。新增的虚函数不会干扰虚析构函数的调用顺序和机制,它只是在虚函数表中增加了一个新的函数指针,用于实现多态调用新增虚函数的功能。