#include <iostream>
using namespace std;
class A {
public:
A() {
this->fun();
}
virtual void fun() {
cout << "A fun" << endl;
}
};
class B :public A {
public:
B() {
this->fun();
}
virtual void fun() {
cout << "B fun" << endl;
}
};
int main() {
B b;
return 0;
}
输出:
所以在构造函数中完全可以调用虚函数,只是调用的语义不符预期,在A()中的this类型是A *指针,我们期望调用的是B::fun(),但是实际上调用的是A::fun()。
原因也很简单,仔细过一下构造函数的执行流程即可。调用B的构造函数,先调用A的构造函数,调用A的构造函数,先按照A对象的内存布局进行初始化,因为虚表指针是放在顶部的,先初始化虚表指针,指向虚表(虚表在编译期就生成),之后按照声明顺序初始化成员变量。最后调用构造函数{ }中的代码。由此可见调用this->fun( )时已经设定好虚表指针,所以调用不会有任何问题。之后B将虚表指针指向自己的虚表,初始化自己的成员变量,最后调用B(){ }中的代码this->fun( ),这个时候对象顶部的虚表指针指向B的虚表,调到的自然是B::fun( )。
析构函数完全相反,先调用析构函数{ }中的代码。