What's wrong with Singleton implementation?

Read the question carefully, please.

I was using this base class for my types where I need the Singleton pattern:

#pragma once

template<typename T>
class singleton
{
private:
    static T* g_pInstance;

public:
    static T* getInstance()         { return g_pInstance; }

public:
    singleton()                     { g_pInstance = (T*)this; }
    ~singleton()                    { if(g_pInstance == this) g_pInstance = nullptr; }
};

template<typename T>
T* singleton<T>::g_pInstance = nullptr;

Usage (no *cpp file):

class Any : public singleton<Any> { /* Done */ }

However, now I have a strange situation using such class from static library, g_pInstance pointer is already set to 0xccccccc (not initialized with zero), before anything was fine.

What is the reason?

UPDATE: compiler: vs 2013 x86

Answers


MSVC has some issue with initializing template statics. It's not something specific to your case. I believe this could be a solution:

template<> Any* singleton<Any>::g_pInstance = nullptr;

Your singleton is not exactly thread safe, but I guess you know that already:-)


Check this out for a simple singleton implementation Singleton instance declared as static variable of GetInstance method

That eliminates your instance pointer initialization issue. Agree with Luu, VC has value of 0xcccccccc assigned to uninitialized pointers. Singleton is bad, as criticized by many, but I still can't completely avoid it :-(

To try answer why the instance pointer is not nullptr when getInstance is invoked. I assume there are different compilation units in the application. If the posted code is in compilation unit A, and the instance pointer exists in static scope of this A compilation unit. I also assume there exist a compilation unit B that have a class Any object declared in static scope of compilation unit B. Since C++ runtime guarantees initialization order of only within same compilation unit, but not across multiple compilation units. The initialization of class Any object in compilation unit B could happen before the initialization of the instance pointer in compilation unit A. That will cause the observation of 0xcccccccc in the instance pointer when getInstance is invoked.


implement a singleton without exposing it to a class, so you dont need to initialize it in source. And make private constructor and copy constructor. Im not sure why you need that casting stuff. You can do like this:

#pragma once

template<typename T>
class singleton
{
private:
    singleton();

    singleton(const singleton&);

public:
    static T& getInstance()
    {
         static T instance;
         return instance;
    }
};

I agree with those that complain about your "singleton" class - it enables multiple instances, so it's not a singleton in the standard sense of the term. But if I understand your question correctly, what's actually bothering you is that Any::getInstance() is not initialized by the nullptr assignment, right?

If so, that's an issue I fail to reproduce with g++ (GCC) 4.8.3, clang version 3.4.2, or on ideone. I recommend trying to use your precise code on different compilers to see if you can reproduce the error there. If you can't, it might be a compiler issue: since from what I know, the initialization line you used is indeed the proper way to initialize a static template data member.


Need Your Help

single process on php

php cron

I need to generate some charts and reports, but only when my DB is modified. Because the time needed to generate the reports varies between 2 and 4 seconds and the number of reports varies too I'm

update custom field if blank

wordpress custom-fields

need to update a custom field value if it is blank mis if it has any value not want to do anything