What is the use of having destructor as private?

C++PrivateDestructor

C++ Problem Overview


What is the use of having destructor as private?

C++ Solutions


Solution 1 - C++

Basically, any time you want some other class to be responsible for the life cycle of your class' objects, or you have reason to prevent the destruction of an object, you can make the destructor private.

For instance, if you're doing some sort of reference counting thing, you can have the object (or manager that has been "friend"ed) responsible for counting the number of references to itself and delete it when the number hits zero. A private dtor would prevent anybody else from deleting it when there were still references to it.

For another instance, what if you have an object that has a manager (or itself) that may destroy it or may decline to destroy it depending on other conditions in the program, such as a database connection being open or a file being written. You could have a "request_delete" method in the class or the manager that will check that condition and it will either delete or decline, and return a status telling you what it did. That's far more flexible that just calling "delete".

Solution 2 - C++

Such an object can never be created on the stack. Always on the heap. And deletion has to be done via a friend or a member. A product may use a single Object hierarchy and a custom memory-manager -- such scenarios may use a private dtor.

#include <iostream>
class a {
    ~a() {}
    friend void delete_a(a* p);
};


void delete_a(a* p)  {
    delete p;
}

int main()
{
    a *p = new a;
    delete_a(p);

    return 0;
}

Solution 3 - C++

When you do not want users to access the destructor, i.e., you want the object to only be destroyed through other means.

http://blogs.msdn.com/larryosterman/archive/2005/07/01/434684.aspx gives an example, where the object is reference counted and should only be destroyed by the object itself when count goes to zero.

Solution 4 - C++

COM uses this strategy for deleting the instance. COM makes the destructor private and provides an interface for deleting the instance.

Here is an example of what a Release method would look like.

int MyRefCountedObject::Release() 
{
 _refCount--;
 if ( 0 == _refCount ) 
 {
    delete this;
    return 0;
 }
 return _refCount;
}

ATL COM objects are a prime example of this pattern.

Solution 5 - C++

Adding to the answers already present here; private constructors and destructors are quite useful while implementing a factory where the created objects are required to be allocated on the heap. The objects would, in general, be created/deleted by a static member or friend. Example of a typical usage:

class myclass
{
public:
    static myclass* create(/* args */)  // Factory
    {
        return new myclass(/* args */);
    }
    
    static void destroy(myclass* ptr)
    {
        delete ptr;
    }
private:
    myclass(/* args */) { ... }         // Private CTOR and DTOR
    ~myclass() { ... }                  // 
}

int main ()
{
    myclass m;                          // error: ctor and dtor are private
    myclass* mp = new myclass (..);     // error: private ctor
    myclass* mp = myclass::create(..);  // OK
    delete mp;                          // error: private dtor
    myclass::destroy(mp);               // OK
}

Solution 6 - C++

The class can only be deleted by itself. Useful if you are creating some try of reference counted object. Then only the release method can delete the object, possibly helping you avoid errors.

Solution 7 - C++

I know you were asking about private destructor. Here is how I use protected ones. The idea is you don't want to delete main class through the pointer to class that adds extra functionality to the main.
In the example below I don't want GuiWindow to be deleted through a HandlerHolder pointer.

class Handler
{
public:
    virtual void onClose() = 0;
protected:
    virtual ~Handler();
};

class HandlerHolder
{
public:
    void setHandler( Handler* );
    Handler* getHandler() const;
protected:
    ~HandlerHolder(){}
private:
    Handler* handler_;
};

class GuiWindow : public HandlerHolder
{
public:
    void finish()
    {
        getHandler()->onClose();
    }

    virtual ~GuiWindow(){}
};

Solution 8 - C++

dirkgently is wrong. Here is an example of object with private c-tor and d-tor created on stack (I'm using static member function here, but it can be done with friend function or friend class as well).

#include <iostream>

class PrivateCD
{
private:
	PrivateCD(int i) : _i(i) {};
	~PrivateCD(){};
	int _i;
public:
	static void TryMe(int i)
	{
		PrivateCD p(i);
		cout << "inside PrivateCD::TryMe, p._i = " << p._i << endl;
	};
};

int main()
{
	PrivateCD::TryMe(8);
};

This code will produce output: inside PrivateCD::TryMe, p._i = 8

Solution 9 - C++

It might be a way to deal with the problem in Windows where each module can use a different heap, such as the Debug heap. If that problem isn't handled correctly bad things can happen.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionyesraajView Question on Stackoverflow
Solution 1 - C++Paul TomblinView Answer on Stackoverflow
Solution 2 - C++dirkgentlyView Answer on Stackoverflow
Solution 3 - C++MichaelView Answer on Stackoverflow
Solution 4 - C++VinayView Answer on Stackoverflow
Solution 5 - C++navView Answer on Stackoverflow
Solution 6 - C++Roland RabienView Answer on Stackoverflow
Solution 7 - C++Mykola GolubyevView Answer on Stackoverflow
Solution 8 - C++misicdView Answer on Stackoverflow
Solution 9 - C++Jared OberhausView Answer on Stackoverflow