Sunday, September 14, 2014

C++ Singleton

#include <iostream>

using namespace std;

class Singleton
{
    public:
        static Singleton& getInstance()     // See Note 1.
        {
            static Singleton instance;      // See Note 2.
                                            // Guaranteed to be destroyed.
                                            // Instantiated on first use.
            return instance;
        }

        void Print();

    private:
        Singleton() {};                     // Constructor? (the {} brackets) are needed here.
                                            // Dont forget to declare these two. You want to make sure they
                                            // are unaccessable otherwise you may accidently get copies of
                                            // your singleton appearing.
        Singleton(Singleton const&);        // Copy Constructor. Don't Implement
        void operator=(Singleton const&);   // Assignment Operator. Don't implement
};

void Singleton::Print()
{ 
    cout << "I am a singleton" << endl;
}

int main(int argc, char *argv[])
{
    Singleton &S1 = Singleton::getInstance();    // Create/Instantiate Singleton 
    S1.Print();
    Singleton::getInstance().Print();

    system("PAUSE");
    return EXIT_SUCCESS;
}

Note 1. Why does everybody want to return a singleton as a pointer? Returning it as a reference seems much more logical! You should never be able to free a singleton manually. How do you know who is keeping a reference to the singleton? If you don't know (or can't guarantee) nobody has a reference (in your case via a pointer) then you have no business freeing the object. Note 2. Use the static in a function method. This guarantees that it is created and destroyed only once. It also gives you lazy initialization for free. This also means I don't need to add the object as a member because I have a static function with a static object inside it? Exactly, the object lives from first call to program termination, so it cannot be a plain data member. Note: Use a Singleton if:

  • If you need to have one and only one object of a type in system
Do not use a Singleton if:
  • If you want to save memory
  • If you want to try something new
  • If you want to show off how much you know
  • Because everyone else is doing it (See cargo cult programmer in wikipedia)
  • In user interface widgets
  • It is supposed to be a cache
  • In strings
  • In Sessions
  • I can go all day long
How to create the best singleton:
  • The smaller, the better. I am a minimalist
  • Make sure it is thread safe
  • Make sure it is never null
  • Make sure it is created only once
  • Lazy or system initialization? Up to your requirements
  • Sometimes the OS or the JVM creates singletons for you (e.g. in Java every class definition is a singleton)
  • Provide a destructor or somehow figure out how to dispose resources
  • Use little memory
If you need one and only one object, you create one and only one.
If there is no logical way that two instances could ever be accommodated without irreversibly corrupting the application, you should consider making it a singleton.
And then there's the other aspect, global access: If you don't need global access to the instance, it shouldn't be a singleton.

No comments:

Post a Comment