Is the Zero Rule used for classes with virtual methods?

I find the Rule of Zero , also mentioned in Peter Sommerlads Slides (p. 32), is very convincing.

Although, it seems, I remember that there was a strict rule: you need to define a virtual descriptor if the class has virtual members and is actually received.

struct Base { virtual void drawYourself(); virtual ~Base() {} }; struct Derived : public Base { virtual void drawYourself(); }; 

The body of the destructor may even be empty (it only needs an entry in vtbl).

I seem to remember that when using hierarchy

 int main() { Base *obj = new Derived{}; obj->drawYourself(); // virtual call to Derived::drawYourself() delete obj; // Derived::~Derived() _must_ be called } 

then it is important that delete obj call the correct destructor . Is it correct that if I left the destructor definition completely, it would not become virtual , and therefore the wrong d'tor would be called?

 struct Base { virtual void drawYourself(); // no virtual destructor! }; 

This leads me to my last question:

  • Is the "Rule of Zero" also true in hierarchies with virtual methods.
  • or do I need to define a virtual destructor in these cases?

Edit: As I was reminded in response, my version of 1sr had the wrong assumptions. The corresponding (virtual) destructor is in Base , not Derived . But my question is: Do I need to declare (virtual) destructors at all?

+8
c ++ c ++ 11 destructor virtual-destructor rule-of-zero
source share
1 answer

This is actually the base destructor that should be declared virtual, and it is automatically virtual in the derived classes:

 struct Base { virtual void drawYourself(); virtual ~Base() = default; }; struct Derived : public Base { virtual void drawYourself(); }; 

But apart from this, rule 0 is still preserved.

If you do it the way you did it, or if you leave the virtual destructor, you simply get undefined behavior when delete bind the derived object using the base pointer.

+5
source share

All Articles