default override of virtual destructor

前端 未结 7 949
孤独总比滥情好
孤独总比滥情好 2021-02-01 12:50

Everyone knows that the desructor of base class usually has to be virtual. But what is about the destructor of derived class? In C++11 we have keyword \"override\" and ability t

相关标签:
7条回答
  • 2021-02-01 13:02

    I think "override" is kind of misleading on destructor. When you override virtual function, you replace it. The destructors are chained, so you can't override destructor literally

    0 讨论(0)
  • 2021-02-01 13:03

    Is it correct to use both keywords "override" and "=default" in the destructor of Child class? Will compiler generate correct virtual destructor in this case?

    Yes, it is correct. On any sane compiler, if the code compiles without error, this destructor definition will be a no-op: its absence must not change the behavior of the code.

    can we think that it is good coding style

    It's a matter of preference. To me, it only makes sense if the base class type is templated: it will enforce a requirement on the base class to have a virtual destructor, then. Otherwise, when the base type is fixed, I'd consider such code to be noise. It's not as if the base class will magically change. But if you have deadheaded teammates that like to change things without checking the code that depends on what they may be possibly breaking, it's best to leave the destructor definition in - as an extra layer of protection.

    0 讨论(0)
  • 2021-02-01 13:11

    There is (at least) one reason for using override here -- you ensure that the base class's destructor is always virtual. It will be a compilation error if the derived class's destructor believes it is overriding something, but there is nothing to override. It also gives you a convenient place to leave generated documentation, if you're doing that.

    On the other hand, I can think of two reasons not to do this:

    • It's a little weird and backwards for the derived class to enforce behavior from the base class.
    • If you define a destuctor in the header (or if you make it inline), you do introduce the possibility for odd compilation errors. Let's say your class looks like this:

      struct derived {
          struct impl;
          std::unique_ptr<derived::impl> m_impl;
          ~derived() override = default;
      };
      

      You will likely get a compiler error because the destructor (which is inline with the class here) will be looking for the destructor for the incomplete class, derived::impl.

      This is my round-about way of saying that every line of code can become a liability, and perhaps it's best to just skip something if it functionally does nothing. If you really really need to enforce a virtual destructor in the base class from the parent class, someone suggested using static_assert in concert with std::has_virtual_destructor, which will produce more consistent results, IMHO.

    0 讨论(0)
  • 2021-02-01 13:11

    The CPP Reference says that override makes sure that the function is virtual and that it indeed overrides a virtual function. So the override keyword would make sure that the destructor is virtual.

    If you specify override but not = default, then you will get a linker error.

    You do not need to do anything. Leaving the Child dtor undefined works just fine:

    #include <iostream>
    
    struct Notify {
        ~Notify() { std::cout << "dtor" << std::endl; }
    };
    
    struct Parent {
        std::string a;
        virtual ~Parent() {}
    };
    
    struct Child : public Parent {
        std::string b;
        Notify n;
    };
    
    int main(int argc, char **argv) {
        Parent *p = new Child();
        delete p;
    }
    

    That will output dtor. If you remove the virtual at Parent::~Parent, though, it will not output anything because that is undefined behavior, as pointed out in the comments.

    Good style would be to not mention Child::~Child at all. If you cannot trust that the base class declared it virtual, then your suggestion with override and = default will work; I would hope that there are better ways to ensure that instead of littering your code with those destructor declarations.

    0 讨论(0)
  • 2021-02-01 13:12

    override is nothing more than a safety net. Destructor of the child class will always be virtual if base class destructor is virtual, no matter how it is declared - or not declared at all (i.e. using implicitly declared one).

    0 讨论(0)
  • 2021-02-01 13:16

    Though destructors are not inherited there is clear written in the Standard that virtual destructors of derived classes override destructors of base classes.

    From the C++ Standard (10.3 Virtual functions)

    6 Even though destructors are not inherited, a destructor in a derived class overrides a base class destructor declared virtual; see 12.4 and 12.5.

    On the other hand there is also written (9.2 Class member)

    8 A virt-specifier-seq shall contain at most one of each virt-specifier. A virt-specifier-seq shall appear only in the declaration of a virtual member function (10.3).

    Though destructors are called like special member functions nevertheless they are also member functions.

    I am sure the C++ Standard should be edited such a way that it was unambiguous whether a destructor may have virt-specifier override. At present it is not clear.

    0 讨论(0)
提交回复
热议问题