我正在使用gcc.我知道当我们销毁由基类指针指向的派生类对象时,虚拟析构函数如何解决问题.我想知道它们是如何工作的?
class A
{
public:
A(){cout<<"A constructor"<<endl;}
~A(){cout<<"A destructor"<<endl;}
};
class B:public A
{
public:
B(){cout<<"B constructor"<<endl;}
~B(){cout<<"B destructor"<<endl;}
};
int main()
{
A * a = new B();
delete a;
getch();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当我将A的析构函数更改为虚函数时,问题就解决了.什么是内部工作.为什么我要将A的析构函数设为虚拟.我想知道A和B的vtable会发生什么?
虚拟析构函数只是一个虚函数,所以它遵循相同的规则.
当你调用时delete a,隐式调用析构函数.如果析构函数不是虚拟的,则会调用a->~A()它,因为它被称为每个其他非虚函数.
但是,如果析构函数是虚拟的,则会~B()按预期调用:析构函数是虚函数,因此调用的是派生类的析构函数,而不是基类.
编辑:
请注意,在派生类的析构函数完成后,将隐式调用基类的析构函数.这与通常的虚函数不同.
您需要知道的关键是,在上面的代码中不使用虚拟析构函数是未定义的行为,这不是您想要的。虚拟析构函数就像任何其他虚拟函数一样 - 当您调用程序时delete,程序将决定在运行时正确调用哪个析构函数,从而解决您的问题。