[英]Why should the destructor of base classes be virtual?
in C++: Why should the destructor of base classes be virtual?在 C++ 中:为什么基类的析构函数应该是虚拟的?
The better question is when and why .更好的问题是何时以及为什么。 Your question indicates that you think all base classes should have virtual destructors, which is not quite true.您的问题表明您认为所有基类都应该具有虚拟析构函数,这并不完全正确。
It would make it impossible to apply the empty base class optimization, and could multiply the size of classes up to 16 times than what it would be without virtual
on common platforms.它将无法应用空基 class 优化,并且可以将类的大小比在通用平台上没有virtual
的情况下增加多达 16 倍。
A virtual
destructor is needed when you delete
an object whose dynamic type is DerivedClass
by a pointer that has type BaseClass*
.当您通过具有类型BaseClass*
的指针delete
动态类型为DerivedClass
的 object 时,需要virtual
析构函数。 The virtual
makes the compiler associate information in the object making it able to execute the derived class destructor. virtual
使编译器关联 object 中的信息,使其能够执行派生的 class 析构函数。 Missing the virtual
in such case causes undefined behavior.在这种情况下缺少virtual
会导致未定义的行为。
If you don't need this, and your class is only used as a base class, it's best to make the destructor protected
, thus preventing that users accidentally delete
in the described way.如果您不需要这个,并且您的 class 仅用作基础 class ,最好使析构函数protected
,从而防止用户以所述方式意外delete
。
You want them to be virtual so that all subclass destructors are automatically called when the object is destroyed, even if it is destroyed through a pointer to the base class.您希望它们是虚拟的,以便在 object 被销毁时自动调用所有子类析构函数,即使它是通过指向基础 class 的指针而被销毁的。 In the following code:在以下代码中:
class base {
public:
virtual ~base() { }
};
class derived : public base {
public:
~derived() { } // Inherits the virtual designation
};
int main(void)
{
base *b = new derived;
delete b;
}
The derived destructor will only be called if the base destructor is virtual.派生的析构函数只有在基析构函数是虚函数时才会被调用。
As Magnus indicates, you don't have to do this if you aren't taking advantage of polymorphism.正如 Magnus 所指出的,如果您不利用多态性,则不必这样做。 However, I try to develop the habit of declaring all my destructors virtual.但是,我尝试养成将所有析构函数声明为虚拟的习惯。 It protects me against the case where I should have declared them virtual but forget to do so.它可以保护我免受我应该将它们声明为虚拟但忘记这样做的情况。 As Johannes indicates, this habit can impose a small space and performance penalty when the virtual designation is not needed.正如 Johannes 所指出的,当不需要虚拟指定时,这种习惯会造成很小的空间和性能损失。
For situations like this:对于这样的情况:
class A
{
virtual ~A();
};
class B:A
{
~B();
};
A *a = new B(); //legal, since it's a downcast
delete a; //Unless the destructor is virtual, ~A() is called here instead of ~B().
They dont have to be virtual unless you are using polymorphism.除非您使用多态性,否则它们不必是虚拟的。 If you do use polymorphism they need to be virtual so that the destructors of inherited classes are guaranteed to be called, so inherited classes can do their clean up.如果您确实使用多态性,它们需要是虚拟的,以便保证调用继承类的析构函数,因此继承类可以进行清理。
It should be virtual to ensure that the destructor of the inherited classes are the ones actually getting called at runtime instead of the base class destructor being called.它应该是虚拟的,以确保继承类的析构函数是在运行时实际调用的析构函数,而不是被调用的基本 class 析构函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.