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?
deletepolymorphically. - Shoe= defaulting special members does not violate the Ro0 in any way. The important part is, that you don't implement their functionality yourself and instead derive it from building blocks likeunique_ptrandvector, which handle a single responsibility. And tbh, even as you have it, without= default, is fine for a destructor - since you don't manually do anything in it. Everything is still handled by the appropriate members' destructors. - Xeostd::shared_ptr<Base>, if constructed fromDerived*(ormake_shared<Derived>) will clean-up by callingDerived::~Derived()and does not requireBase::~Base()to be virtual. - Ben Voigtstd::shared_ptr. Instd::unique_ptryou don't get that behavior, because the custom deleter is part of the type (i.e. allstd::unique_ptr<Base, ThisDeleterType>will delete objects the same way). Sounique_ptrcustom deleters really are not useful for polymorphism. - Ben Voigt