views:

3023

answers:

7

What is the use of having destructor as private?

+32  A: 

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 either delete or or decline it, and return a status telling you what it did. That's far more flexible that just calling "delete".

Paul Tomblin
+21  A: 

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.

Michael
+1 for being 30 seconds slower than me, but having a good example.
Paul Tomblin
+5  A: 

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.

FigBug
+12  A: 

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;
}
dirkgently
Deletion has to be done via a friend /or member/
MSalters
This was already mentioned -- so I skipped it. Will updata (on second reading my statement looks a bit too strong).
dirkgently
A: 

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.

Jared Oberhaus
+2  A: 

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(){}
};
Mykola Golubyev
+5  A: 

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.

Vinay