Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does "The Rule of Zero" also apply for classes with virtual methods?

I find The rule of Zero as also mentioned on Peter Sommerlads Slides (p.32) very compelling.

Although, I seem to remember that there was a strict rule that one has to define the destructor virtual, if the class has virtual members and is actually derived.

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 the entry in the vtbl).

I seem to remember that when use the 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 calls the correct destructor. Is it correct, that if I left out the destructor definition totally, 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 final question:

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

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

like image 964
towi Avatar asked Feb 07 '14 20:02

towi


1 Answers

It's actually the base destructor that has to be declared virtual, and it's automatically virtual in derived classes:

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

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

But other than that, the rule of zero still holds.

If you do it the way you did it, or if you leave out the virtual destructor, you simply get undefined behavior when deleteing a derived object through a base pointer.

like image 189
user3175411 Avatar answered Nov 10 '22 04:11

user3175411