Home > Software engineering >  Does base class destructor need to be virtual if only some derived classes are polymorphic?
Does base class destructor need to be virtual if only some derived classes are polymorphic?

Time:02-18

I have a similar situation to this question where I have 2 classes that share a public interface function, and so I've pulled that function (manage_data_in_memory() in the example) out into a base class which the 2 classes inherit from. However, the 2 classes are otherwise not related, and one of them is polymorphic, whereas the other one isn't. It is also not expected for someone to declare an object of this base class, as it exists only to prevent code duplication (is there a way to enforce this? I know pure virtual functions can prevent an object from being instantiated, but declaring a dummy pure virtual that does nothing in the derived class seems like bad design).

Does the base class destructor need to be virtual in this case? This would force the other derived class to also have a virtual destructor, which it doesn't need. Thanks.

So now I have code in the form

class base  {  // don't instantiate an object of this, is there a way to enforce this?
 public: 
   void manage_data_in_memory();
 protected:
    data;        
 };
    
 class derived : public base
 {
 public:
    void sendData();
 private:
     virtual void sendDataHelper(); // override this in derived classes which need to send custom data in addition to the default data
 };
    
 class derived2 : public base
 { 
  public:
   void do_Z_On_data()
 };

CodePudding user response:

The destructor of a base class must be virtual if and only if an instance of a derived class will be destroyed through a pointer to the base object. If the destructor isn't virtual in such case, then the behaviour of the program would be undefined. Example:

struct Base {
    // ...
};
struct Derived : Base {};


std::unique_ptr<Base> ptr = std::make_unique<Derived>();
// Base::~Base must be virtual

It's possible to prevent the user of the class from doing this (at least by accident) by using private inheritance. If the destructor isn't virtual, then inheritance should be private except possibly in special cases where you need a standard layout class.


is this because private inheritance would make the destructor private

No, private inheritance doesn't make destructor private.

which prevents anyone from declaring an object of Base?

No, and declaring an object of Base isn't a problem.

Private inheritance prevents conversion from derived pointer into a base pointer outside the member functions of the derived class (and friends). The inability acquire a pointer to base of the derived class would prevent the user from deleting a derived object through such pointer.

  • Related