Singleton Class in C++

11,300

Solution 1

For a start, I think:

singleton();

should be:

instance = new singleton();

The way you have it, you're not actually storing the newly instantiated object so instance will always be null.

It's also good form to explicitly set statics with:

singleton *singleton::instance = 0;

(outside the class definition).

In fact, it's possibly better to start with the baseline singleton code and work your way up from there. This is a standard-form pointer version:

#include <iostream>

class singleton {
    protected:
        static singleton *instance;
        singleton() { }
    public:
        static singleton *getInstance() {
            if (instance == 0)
                instance = new singleton();
            return instance;
        }
};
singleton *singleton::instance = 0;

int main() {
    singleton *s1 = singleton::getInstance();
    singleton *s2 = singleton::getInstance();
    std::cout << s1 << '\n';
    std::cout << s2 << '\n';
    return 0;
}

You can see that both pointers are the same from the output:

0xbc0358
0xbc0358

Or the reference version, since that seems to be what you're aiming for:

#include <iostream>

class singleton {
    protected:
        static singleton *instance;
        singleton() { }
    public:
        static singleton& getInstance() {
            if (instance == 0)
                instance = new singleton();
            return *instance;
        }
};
singleton *singleton::instance = 0;

int main() {
    singleton &s1 = singleton::getInstance();
    singleton &s2 = singleton::getInstance();
    std::cout << &s1 << '\n';
    std::cout << &s2 << '\n';
    return 0;
}

Solution 2

In your definition file, you need the definition of instance:

singleton* singleton::instance = NULL;

You should separate your definition from your declaration if you want to use the singleton in multiple translation units.

Also, the way it's usually done, is not having an initialize method:

static singleton* getInstance()
{ 
    if(instance==NULL)
        instance = new singleton();
    return instance;
}

There are lots of discussions on SO whether singletons are good or bad, with the general consensus that they should be avoided. You should also check them out.

Solution 3

You need to define the static member variable instance. Somewhere in global scope (for example between the class and the main function) add the following line:

singleton *singleton::instance = 0;  // use 'nullptr' if your compiler support it

Also, you can put the initialization of the instance in getInstance:

static singleton& getInstance()
{
    if (instance == 0)
        instance = new singleton;
    return *instance;
}

and remove the initialize function.

You might also want to make the constructor private instead of protected, as well as having private copy-constructor and assignment functions to prevent copying and assignment.

Share:
11,300
Rohit Vipin Mathews
Author by

Rohit Vipin Mathews

Xamarin Developer (Forms / Android / iOS / Windows) Full Stack .NET Developer (ASP.NET / MVC / WebAPI / WPF / WinForms / MS SQL / .NET Core) Linked In

Updated on June 04, 2022

Comments

  • Rohit Vipin Mathews
    Rohit Vipin Mathews almost 2 years

    I have used singleton calss following the example:

    singleton class

    But i get the error as "Unresolved external symbols"

    this is the code i tried out:

    #include<iostream>
    using namespace std;
    
    class singleton
    {
        int value;
        static singleton *instance;
    protected:
        singleton()
        {
            value=0;
        }
    public:
        static void initialize()
        {
            if(instance==NULL)
                singleton();
            else
                cout<<"An instance of singleton already exist...";
        }
        static singleton& getInstance()
        { 
            return *instance; 
        }
        int getValue() 
        { 
            return value; 
        }
    
    };
    
    void main()
    {
        singleton::initialize();
    }
    

    A little bit explanation on Singleton classes would be really great. The scenario its used. advantages and drawbacks. Alternatives to Singleton. etc

  • James Kanze
    James Kanze over 12 years
    That may be the general consensus in SO (although I'm not sure of it---I think it's just a case of the opponents being more vocal), but it's certainly not in general. The singleton pattern is widely used and there's nothing wrong with it where appropriate.
  • GManNickG
    GManNickG over 12 years
    @JamesKanze: Here we go again... :) Widely used doesn't mean justifiably used. It just means many misguided people are using singletons when they don't really need to. We aren't saying it won't work, but we are saying you're wasting effort on bad design.
  • Rohit Vipin Mathews
    Rohit Vipin Mathews over 12 years
    So it really hazardous to use singleton in multithreading environments?
  • James Kanze
    James Kanze over 12 years
    @GMan But it's just you saying it. There's no real evidence, and there's a large body of competent programmers who do you singletons, without problems. On the whole, there's anything but a consensus that singletons represent a bad design; in fact, there's very close to a consensus that they are appropriate in certain situations. (Now, if your argument is only that they can be misused, or that they are often used when not appropriate, the same thing can be said of many other C++ techniques. Starting with templates.)
  • James Kanze
    James Kanze over 12 years
    @CodingMastero A singleton is shared between all of the threads, so some precautions are in order. Just like any object shared between more than one thread. Given that it's a widely known and widely studied pattern, it's probably easier to get using singletons right than using other shared objects (but it's even easier, in many cases, to avoid sharing objects completely).
  • Luchian Grigore
    Luchian Grigore over 12 years
    I think the consensus is directed towards "you rarely really need a singleton". Most programmers use them when they aren't really needed. And using them without knowing the pitfalls is just as bad.
  • Mike Seymour
    Mike Seymour over 12 years
    An explicit "initialize" function allows you to ensure it's initialised before multiple threads might have access - your initialisation isn't thread-safe (and also gives a memory leak). Singletons (and global objects in general) are surprisingly difficult to manage safely in C++, which is one more reason to avoid them.
  • GManNickG
    GManNickG over 12 years
    @JamesKanze: What's one thing that needs to be a singleton instead of a global?
  • paxdiablo
    paxdiablo over 12 years
    @mike, I question the need for an exolicit initialise method when all you need to do is to call get instance from the main thread before kicking off any other threads.
  • James Kanze
    James Kanze over 12 years
    @LuchianGrigore There's probably something in that. A singleton is a form of global variable, and in general, global variables are probably overused. But that's true for a number of things. Usually following fashion---singleton's were a fashion for a while, with the result of their being used regardless of whether they were appropriate or not. The same thing can be said for smart pointers and templates, today. When I first started C++, it was inheritance. In all cases, the underlying technique is useful. When used appropriately, and not systematically.
  • Mike Seymour
    Mike Seymour over 12 years
    @paxdiablo: With that approach, there's no way for the accessor to assert that it's been safely initialised; if you forget, then the only indication will be random, unreproducible bugs. If you're going to use something as error-prone as a global object (whether or not you dress it up in a weird "pattern"), it's worth making it as safe to use as possible.
  • Mike Seymour
    Mike Seymour over 12 years
    @JamesKanze: Maybe I'm just following fashion when I insist that dependencies should be explicit, interfaces should be separated from implementations, and components should be loosely coupled and testable in isolation; but I've certainly found that these things make large projects easier to manage, and that global variables (disguised or not) work against them. I've never encountered a use case for a global that couldn't be better met by a sensibly scoped variable, passed by reference to whatever needs it; and I've spent more time than I'd like fixing unnecessary, badly implemented singletons.
  • James Kanze
    James Kanze over 12 years
    @MikeSeymour Used appropriately, singletons reduce coupling. Significantly. That's the real reason to use them. As for anecdotal evidence on having seen misuse or poorly implemented singletons... if I rejected everything I've seen that has been misused or poorly implemented, there wouldn't be anything left for me to use.
  • Rohit Vipin Mathews
    Rohit Vipin Mathews over 12 years
    Thanks for all the help guys!! Atlast i made thread safe singleton class(hope so)!!
  • Rohit Vipin Mathews
    Rohit Vipin Mathews about 12 years
    Oh yeah it did good for a start but even though it did not implement a real good singleton class