Why should the destructor of base classes be virtual?

前端 未结 5 1161
长情又很酷
长情又很酷 2021-02-05 19:14

in C++: Why should the destructor of base classes be virtual?

相关标签:
5条回答
  • 2021-02-05 19:41

    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.

    0 讨论(0)
  • 2021-02-05 19:42

    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. 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. 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.

    0 讨论(0)
  • 2021-02-05 19:46

    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.

    0 讨论(0)
  • 2021-02-05 19:50

    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.

    A virtual destructor is needed when you delete an object whose dynamic type is DerivedClass by a pointer that has type BaseClass*. The virtual makes the compiler associate information in the object making it able to execute the derived class destructor. Missing the virtual in such case causes undefined behavior.

    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.

    0 讨论(0)
  • 2021-02-05 19:52

    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().
    
    0 讨论(0)
提交回复
热议问题