为什么构造函数和析构函数中不要调用virtual函数
时间: 2024-03-18 13:45:35 浏览: 21
在构造函数和析构函数中调用 virtual 函数可能会导致意外的行为,因为在对象的生命周期的某些阶段,虚函数表(也称为 vtable)可能不会被完全初始化或已被部分或完全销毁。这可能会导致未定义的行为,甚至会导致程序崩溃。因此,一般来说,建议不要在构造函数和析构函数中调用 virtual 函数,以避免潜在的问题。
相关问题
抽象类指针调用构造函数和析构函数吗
抽象类不能被实例化,因此抽象类的构造函数和析构函数都不能被直接调用。当通过抽象类指针指向其派生类的对象时,实际上是调用了派生类的构造函数,而当抽象类指针指向的对象被销毁时,实际上是调用了派生类的析构函数。
例如,假设有一个抽象类AbstractClass和它的派生类DerivedClass:
```
class AbstractClass {
public:
virtual void func() = 0;
};
class DerivedClass : public AbstractClass {
public:
DerivedClass() {
cout << "DerivedClass constructor" << endl;
}
~DerivedClass() {
cout << "DerivedClass destructor" << endl;
}
void func() {
cout << "DerivedClass func" << endl;
}
};
```
使用抽象类指针指向DerivedClass的对象,可以看到构造函数和析构函数的调用:
```
AbstractClass *ptr = new DerivedClass;
ptr->func();
delete ptr;
```
输出结果为:
```
DerivedClass constructor
DerivedClass func
DerivedClass destructor
```
可以看到,当通过抽象类指针指向DerivedClass的对象时,先调用了DerivedClass的构造函数,然后调用了DerivedClass的成员函数func(),最后通过抽象类指针delete对象时,调用了DerivedClass的析构函数。
在构造函数和析构函数调用 virutal 函数会产生什么后果?结合 Demo 分析。
在构造函数中调用虚函数会导致在构造函数执行期间,这个虚函数的行为是不确定的。
在构造函数的执行过程中,一个对象的状态还没有完全被初始化,如果在这个时候调用了虚函数,那么这个虚函数所在的类型(即这个虚函数是属于哪个类的)还没有被完全构造,这个虚函数的行为是不确定的。
析构函数中调用虚函数是没有问题的,析构函数是在对象被销毁之前调用的,此时对象的状态已经被完全构造完毕,调用虚函数是没有问题的。
下面是一个简单的示例:
```
#include <iostream>
class Base
{
public:
Base()
{
std::cout << "Base Constructor" << std::endl;
virtualFunction();
}
virtual ~Base()
{
std::cout << "Base Destructor" << std::endl;
virtualFunction();
}
virtual void virtualFunction()
{
std::cout << "Base virtualFunction" << std::endl;
}
};
class Derived : public Base
{
public:
Derived()
{
std::cout << "Derived Constructor" << std::endl;
}
~Derived()
{
std::cout << "Derived Destructor" << std::endl;
}
void virtualFunction()
{
std::cout << "Derived virtualFunction" << std::endl;
}
};
int main()
{
Derived d;
return 0;
}
```
输出结果为:
```
Base Constructor
Base virtualFunction
Derived Constructor
Derived Destructor
Base Destructor
```
可以看到