0

In this example, I expected that the instance was re-initialzed to NULL everytime. Thus, it shouldn't have worked, it should do new everytime. But, it works actually as singleton. Thus,the new is called only once. Why it works? I am confused here.

class Factory_model
{
public:

    static  Factory_model*    Instance(void);

};

Factory_model*    Factory_model::Instance(void)
{
    static Factory_model* instance = NULL;

    if(instance == NULL)
    {
        qDebug()<< "Creating instance now"<<endl;
        instance = new Factory_model;

    }

    return(instance);
}

int main(int argc, char *argv[])
{

   Factory_model *ptr =  Factory_model::Instance();
   Factory_model *ptr2 =  Factory_model::Instance();
   Factory_model *ptr3 = Factory_model::Instance();
}

The output is the following - Creating instance now

dexterous
  • 6,422
  • 12
  • 51
  • 99
  • Note the difference between `static Factory_model* instance = NULL;` and `static Factory_model* instance; instance = NULL;`. – aschepler Mar 03 '14 at 14:04

4 Answers4

5

I expected that the instance was re-initialzed to NULL everytime.

No, static variables are only initialised once, the first time the program reaches the definition (or earlier if, as here, it can be statically initialised).

Of course, you've got a memory leak, and the object creation isn't thread-safe; but this isn't the place for yet another essay about the perils of the Singleton anti-pattern.

Community
  • 1
  • 1
Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • What memory leak I have injected here? Also, why isn't it thread safe. – dexterous Mar 03 '14 at 14:42
  • @SHREYASJOSHI: There's a `new` with no matching `delete`, therefore a memory leak. If two threads both call the function simultaneously, they might both find the variable to be null, and both create the object. (It's probably not worth trying to fix the leak, as the alternatives will quickly lead to a nightmare of lifetime issues. You can bodge around the threading problem, if necessary, by deliberately calling the accessor before starting threads. Or you can save yourself a lot of pain by giving up on the idea of a Singleton.) – Mike Seymour Mar 03 '14 at 14:45
  • Another definition of a leak is an object with no reference to it; under this definition it is not a leak. – Bryan Mar 03 '14 at 15:55
  • @Bryan: OK; I was using the definition of an object that was created and not destroyed. But lets not get bogged down in semantic quibbling about a remark that's not particularly relevant to the question. – Mike Seymour Mar 03 '14 at 15:59
  • True, also thread safe part is dependent on how I am going to access the common code, a mutex can prevent such conditions. So, it should be consider will making the thread and not here. – dexterous Mar 03 '14 at 16:15
2

The line:

static Factory_model* instance = NULL;

is only executed once; that is what the keyword static means when you use it on a local variable. The initialisation is not executed every time you enter the function.

See The static keyword and its various uses in C++ or http://www.cprogramming.com/tutorial/statickeyword.html

Community
  • 1
  • 1
Bryan
  • 11,398
  • 3
  • 53
  • 78
1

also, have a look at this:

Singleton instance declared as static variable of GetInstance method

...every time c++ static variables and singleton are involved, this is a technique you should know

Community
  • 1
  • 1
Exceptyon
  • 1,584
  • 16
  • 23
0
static Factory_model* instance = NULL;

creates a static storage duration variable called instance and initialises it once. You are correct in that a variant without the static keyword would be initialised each time, but the static makes a difference here.

It's effectively the same as if you had declared it outside the function, but with the added bonus of minimising scope (what can see the variable). Creating a static storage duration variable inside the function means that only the function can see/use it (absent any trickiness in publishing a pointer or reference to it), and it maintains its value across function invocations.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953