0

I need a singleton implementation without using dynamic memory allocation. I tried to implement it like this:

// Singleton.hpp

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

    private:
    Singleton();
    static Singleton& Instance;
};

// Singlton.cpp

Singleton& Singleton::GetInstance()
{
    return Singleton::Instance;
}

Singleton::Singleton()
{
}

As I said this doesn't compiles. I read many articles, I tried to initialize static Singleton& Instance in different ways, but all I get is a new compilation errors. Why this doesn't work? And how to implement a singleton pattern without using dynamic memory allocation?

4 Answers4

2

You need to declare the GetInstance method static as well, otherwise you can only call it on an existing object - and you can't create an existing object because the constructor is private.

P.S. instead of creating the instance as a static member of the class, you can make it a static local variable inside GetInstance.

P.P.S. I just noticed that your Instance variable is a reference that you didn't initialize - that won't work either. Here's my version:

Singleton & GetInstance()
{
    static Singleton Instance;
    return Instance;
}
Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • Sorry! My `GetInstance()` method is actualy static. My fault. As for you solution - yes, I know it, but it seems to me a little ugly and not true object oriented. And why reference won't work in my case? –  Nov 15 '13 at 19:35
  • @Menzoda a reference won't work because you're not initializing it to anything. Somewhere in the program there must be an actual instance of the class. Since you need to make an instance anyway, you can access it directly instead of keeping a reference to it. – Mark Ransom Nov 15 '13 at 19:39
  • Without reference all works fine! Thanks! But for educational purposes can you provide valid code for reference initialization in my case? Is it even possible to use the reference in such cases? Because my attempts have failed. –  Nov 15 '13 at 19:49
  • @Menzoda because the reference is static it needs to be initialized with a static instance. Because the constructor is private the static instance can't be global, it must be a member of the class. That's the logic that led to my recommendation above. – Mark Ransom Nov 15 '13 at 20:00
0

Your definition of Instance should not be reference like Singleton& Instance; in the header. It needs to be Singleton Instance; as it is not a reference but an object.

You have declared Singleton::Instance in the header but not defined it in the source. You need to put Singleton Singleton::Instance; in the source file. Non-const static objects need to be defined in the source file.

You need to declare getInstance method as static so that you won't need an actual object to call it. When it is static, you may call it using Singleton::getInstance();.

Etherealone
  • 3,488
  • 2
  • 37
  • 56
  • Sorry! My `GetInstance()` method is actualy static. My fault. And why I can't use reference in this case? –  Nov 15 '13 at 19:36
  • @Menzoda Because reference is used to refer to an actual objects that is already created. I.E. your `getInstance()` function's return value is (will create) a reference to the actual `Instance` in the class. Also you could use the lazy evaluation (static inside the `getInstance()`) method that others mentioned. That way your class will be initialized on first call to the function instead of startup of your program. – Etherealone Nov 15 '13 at 19:40
0

This way:

class Singleton
{
    public:
        static Singleton& getInstance();
        ~Singleton();

    private:
        Singleton();
        Singleton(Singleton&); // don't implement
        void operator=(const Singleton&); // don't implement
};


#include "singleton.hpp"

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

Singleton::Singleton()
{
}

Singleton::~Singleton()
{
}

Edit:

Following your "OPP-way" of doing it, you just have to initialize your instance variable:

class Singleton
{
    public:
        static Singleton& getInstance();
        ~Singleton();

    private:
        Singleton();
        Singleton(Singleton&); // don't implement
        void operator=(const Singleton&); // don't implement
        static Singleton instance;
};

Singleton Singleton::instance;

Singleton& Singleton::getInstance()
{
    return instance;
}

Singleton::Singleton()
{
    std::cout << "ctor" << std::endl; 
}

Singleton::~Singleton()
{
}

Test with this:

int main() {
    Singleton& s = Singleton::getInstance().getInstance();
    s.getInstance();
}

The constructor will be called just once... But this way you loose the lazy initialization.

Henrique Barcelos
  • 7,670
  • 1
  • 41
  • 66
  • Yes, but as i said to @Mark it seems to me a little ugly and not true object oriented. –  Nov 15 '13 at 19:37
  • Singleton is itself ugly and not OO, what's the problem? – Henrique Barcelos Nov 15 '13 at 19:39
  • Yeap, this works fine. But theoretically, can I use a reference static variable (i.e. `static Singleton& Instance` like in my original question) and initialize it somehow? Because my first error was that reference variable wasn't initialized and when I tried different ways of initialization I got another errors. –  Nov 15 '13 at 20:07
  • You can't use refereces because there is no value to reference yet. Use a non-reference static property just as I pointed out... – Henrique Barcelos Nov 15 '13 at 20:09
0

This is what I did for my singleton class:

I added a data member static int Count ; into my class.

So now I have :

a declaration static Singleton::Count = 0;

and the constructor:

 Singleton()
{
 Count++;
}

My getinstance is:

static Singleton GetInstance() 
    {
       Singleton obj;

    if ( Count == 1)

     return obj;

    }
Rabbiya Shahid
  • 422
  • 3
  • 14