一般情况下,不允许在构造函数或者析构函数中调用虚函数。其实语法上都没有问题,只是会失去多态性。
如果在构造函数中调用虚函数,会先调用父类中的实现,也就失去了多态的性质。
class A {
public:
virtual void print() {
cout << "A" << endl;
}
A() {
print();
}
~A() {
//print();
}
};
class B :public A {
void print() {
cout << "B" << endl;
}
};
int main() {
A* ptr = new B;
return 0;
}
如果在析构函数中调用虚函数,也是同样的失去了多态性。
class A {
public:
virtual void print() {
cout << "A" << endl;
}
A() {
print();
}
~A() {
print();
}
};
class B :public A {
void print() {
cout << "B" << endl;
}
};
int main() {
A* ptr = new B;
delete ptr;
return 0;
}
出现上述结果的原因是因为,构造函数还没有将vptr和vtable初始化完毕,就调用虚函数,此时必然调用的基类中的实现。
而在析构函数中,因为子类的那部分已经被析构掉了,此时在父类的析构函数调用虚函数,调用的也只能是父类中的实现。