mercredi 27 novembre 2019

Which is a better way of handling virtual destructor?

I have a few classes (around 10 in my project) that needs a virtual destructor while also requiring support for std:move and std::copy calls. To keep both copy and move semantics in these classes, I added another class to serve as a base class for these classes:

/*
This class should be inherited by any class that:
- needs a virtual destructor,
- doesn't require explicit definitions of destructor, copy/move constructor/assignment
- needs to support copy and move semantics.

Such classes can inherit from the class defined below to make their destructor virtual,
and keeping copy and move semantics intact.

INFO: This class won't be able to serve it's purpose if any of the 5 mentioned member
functions are explicitly defined in the derived class.
*/

class VirtualDtor
{
protected:
   virtual ~VirtualDtor() = default;
};

This class drew some concerns such as - A derived class may (by mistake or design) explicitly define one or few of the 5 member functions, even after inheriting from VirtualDtor. That would lead to the removal of copy/move semantics defeating the purpose of VirtualDtor. To avoid such scenarios, maintaining rule of 5 by declaring the 5 functions as default in each class individually could bring some clarity about what to expect.

But inheriting from this class will make the code more readable and if we understand it's requirements and usage before inheriting, it will not cause any unexpected behavior.

So I would like to know which is a better way of handling virtual destructors and the rule of 5.

Note: I could have added copy and move member functions too in the VirtualDtor class like it's suggested here. I didn't keep them to avoid the mistaken impression that any class that derives from VirtualDtor will inherit copy and move-semantics which it won't. It will only make the destructor in derived classes virtual. So I skipped the rule of 5 in VirtualDtor.

Aucun commentaire:

Enregistrer un commentaire