36

Is there any difference between a protected and a private destructor in C++? If a base classes destructor is private, I imagine that it is still called when deleting the derived class object.

doron
  • 27,972
  • 12
  • 65
  • 103

4 Answers4

33

If the base class destructor is private or protected then you cannot call delete through the base-class pointer.

Use a protected destructor to prevent the destruction of a derived object via a base-class pointer. It limits access to the destuctor to derived classes. And it prevents automatic (stack) objects of class base.

In effect it is used to allow any other polymorphic use of derived classes via pointers to base, but not allow the users to delete using such a pointer. Example:- Abstract Base Classes / Interfaces.

But a protected, non-virtual destructor on a non-final class seems to be a bug waiting to happen. Assuming you do not provide a destroy() function, you have to eventually make the dtor public. As soon as you do that, you have no further control over the class, and run the risk of polymorphic deletion with a non-virtual dtor, if someone derives further from your class.

Abhay
  • 7,092
  • 3
  • 36
  • 50
  • *But a protected, non-virtual destructor seems to be a bug waiting to happen* seems to contradict to the [Core Guidelines](http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#c35-a-base-class-destructor-should-be-either-public-and-virtual-or-protected-and-non-virtual). – agentsmith Feb 23 '22 at 10:17
  • Added 'non-final' which was the original intent. – Abhay Feb 23 '22 at 18:01
28

Taken from here:

If the constructor/destructor is declared as private, then the class cannot be instantiated.

This is true, however it can be instantiated from another method in the class. Similarly, if the destructor is private, then the object can only be deleted from inside the class as well. Also, it prevents the class from being inherited (or at least, prevent the inherited class from being instantiated/destroyed at all).

Amir Rachum
  • 76,817
  • 74
  • 166
  • 248
11

The following piece of code will result in the compiler error (VC2010): C2248: 'base::~base' : cannot access private member declared in class 'base'

class base
{
    ~base(){}
};

class derived : public base
{
};

int main ()
{
    derived* d = new derived;

    delete d;
}

However, if you change the base destructor to be protected, everything works fine.

Nemanja Trifunovic
  • 24,346
  • 3
  • 50
  • 88
  • 2
    But even if you changed it to `protected`, you couldn't destroy objects through a base class pointer. (In that case it should also be `virtual`, BTW.) Which somewhat defeats many of the purposes of derivation... – sbi Jul 14 '10 at 15:22
6

The answer is that your assumption is wrong. The base class destructor cannot be called when it is private.

Omnifarious
  • 54,333
  • 19
  • 131
  • 194
  • So how does my class get destroyed? – doron Jul 14 '10 at 14:38
  • 2
    @deus-ex-machina399: It cannot. Therefore you cannot derive from it. And you cannot create automatic objects of it. And dynamic objects can never be deleted (unless you provide a member function which does so). – sbi Jul 14 '10 at 15:20