KhanS
KhanS

Reputation: 1195

private destructor for singleton class

Is it compulsory to have a private destructor for a singleton class.

Upvotes: 12

Views: 26364

Answers (7)

Apitronix
Apitronix

Reputation: 273

Having a private destructor as part of a singleton is not required from a programmer's point of view, but essential from a design point of view.

It avoids misuse of the class.

However, if you add a private destructor, you have to instantiate your class:

  • In a function / method: because if you create it as a global variable, you lose the interest of using a singleton (created to avoid global variables).
  • With the correct way to instantiate it: if your destructor is private, your class could not be deleted at the end of your program if you instantiate it as a "classic" local variable, because it can't access to it. So you have to instantiate it like this :
Singleton * potatoe = &Singleton::getInstance();

Here, we create a weak pointer named "potatoe", wich correspond to the address of the result of the "getInstance" function. The consequence is that the destructor will not be called at the end of the function. But because (in "getInstance") the variable is declared "static" in a "static" method, the destructor will be called at the end of the program, without you having to do it.

Here is my code. Feel free to comment it.

// "class.hpp" file
class Singleton {
public:
    static Singleton& getInstance() {
        static Singleton S;
        return S;
    } 
private:
    Singleton();
    ~Singleton();
};

// "main.cpp" file
#include "class.hpp"

int main()
{
        Singleton * patatoe = &Singleton::getInstance();
        Singleton * tomatoe = &Singleton::getInstance();
        Singleton * salad = &Singleton::getInstance();
        return 0;
}

Upvotes: 1

Vadim Sukhorukov
Vadim Sukhorukov

Reputation: 131

In my opinion, the destructor of a signleton should be private. Otherwise somewone is able to call 'delete' for your singleton instance. I know, normally nobody will do it. But if we talk about excellence design, it must be resistant to all possible intended or unitnended damages.

With the modern C++ it is allowed to declare even private destructors for statically constructed objects. Here is my code snippet for Singleton:

class Singleton
{
public:
    static Singleton& GetInstance();

    // Before C++ 11 
private:
    Singleton()  {}
    ~Singleton() {}

    Singleton(const Singleton&);            // Without implementation
    Singleton& operator=(const Singleton&); // Without implementation

    // Since C++ 11
private:
    Singleton()  = default;
    ~Singleton() = default;

public:
    Singleton(const Singleton&)            = delete;
    Singleton& operator=(const Singleton&) = delete;
};

Singleton& Singleton::GetInstance()
{
    static Singleton instance;
    return instance;
}

Upvotes: 9

Michael Aaron Safyan
Michael Aaron Safyan

Reputation: 95499

No, and in general objects in C++ are not given private destructors. Keep in mind that Singleton means that there is only one instance, and so it is construction, not destruction, that needs to be controlled / prevented. Usually a singleton has a private constructor, a public destructor, a private static instance variable, and a public static singleton get / lazy construction function, although there are variations on that pattern.

Upvotes: 3

baris.aydinoz
baris.aydinoz

Reputation: 1950

You may return reference to your singleton instance.

class Factory : public IFactory
    {
    private:
        /**
        * This class should not be instantiated through its constructor. Since, it implements 
        * Singleton pattern.
        */
        Factory();      
    public:
        virtual ~Factory();
        /**
        * Accessor method for singleton instance.
        * \note use this static method to access to operations of this class.
        */
        static IFactory& instance(){
            if(!m_instance.get()){
                m_instance.reset(new Factory());    
            }
            return static_cast<IFactory&>(*m_instance);
        }
        /**
        * \see IFactory::create
        */
        virtual boost::shared_ptr<IConnector> create();
    private:
        /* Singleton instance */
        static boost::scoped_ptr<Factory> m_instance;

    };

Upvotes: 1

Potatoswatter
Potatoswatter

Reputation: 137800

If the singleton is implemented as a variable at global scope, it must have a public destructor. Only public members are accessible at global scope.

If it's declared as a static member or static local within its own class, then the destructor may be private. The destructor is called from within class scope, where it is accessible, when the program exits. That is one way to enforce the object being a singleton. Do you need to strongly enforce that? If so, yes. It depends what you mean by "compulsory."

class A{
private:
    ~A() {}
public:
    static A &getGlobalA() {
        static A a2; // <- or here - better technique
        return a2;   // this is initialized upon 1st access
    };               // and destroyed on program exit

    static A a; // <- constructor, destructor accessed from here
};

A A::a; // <- but "called" from here in terms of control flow

Upvotes: 17

default
default

Reputation: 11635

This might not be what you are looking for.. But for reference, I use it as follows:

// .h
class Foo {
public:
    static Foo* getInstance();
    static void destroy();
private:
    Foo();
    ~Foo();

    static Foo* myInstance;
};

// .cpp
Foo* Foo::myInstance = NULL;

Foo* Foo::getInstance(){
    if (!myInstance){
        myInstance = new Foo();
    }
    return myInstance;
}
void Foo::destroy(){
    delete myInstance;
    myInstance = NULL;
}

Then at the end of my program, I call destroy on the object. As Péter points out the system will reclaim the memory when your program ends, so there is no real reason. The reason I use a destroy is when Ogre complained that I hadn't released all the memory I allocated. After that I just use it as "good manner", since I like cleaning up after myself.

Upvotes: 9

Mark Byers
Mark Byers

Reputation: 838176

All classes have a destructor. If you don't create one the compiler will do so for you. So your question can be reworded to: Does the destructor for a singleton class have to private?

The simple answer is no, it doesn't have to be.

A more interesting question: Is it a good idea to make the destructor of a singleton class private?

Yes, in general, it is a good idea. If you make it private then your client code won't call the destructor by accident. Calling the destructor would cause the singleton to fail for all clients as the instance would become invalid.

Upvotes: 5

Related Questions