user1673206
user1673206

Reputation: 1711

Unresolved external symbol linkage error for a singleton object

I'm trying to understand the meaning of the error I get.

This is a singleton implementation:

class Singleton
{
    private:
        Singleton():m_value(0){};
        static Singleton * m_instance;
        int m_value;

    public:
        static Singleton * GetInstance()
            {
                if(!m_instance)
                {
                    m_instance = new Singleton;
                }

                return m_instance;
            }
        void SetValue(int x){m_value = x;}
        int GetValue(){return m_value;}

        ~Singleton()
        {
            if(m_instance)
                delete m_instance;
        }
    };



Singleton* Singleton::m_instance = 0;


void main()
{
    Singleton * s1 = Singleton::GetInstance();
}

The code compiles and run successfully.

When I remove the line Singleton* Singleton::m_instance = 0;, I get the error:

 error LNK2001: unresolved external symbol "private: static class Singleton * Singleton::m_instance"

I guess the meaning of that line is to set the static variable m_instance to 0.

So I don't understand the syntax of that line- why can't I write just Singleton::m_instance = 0;? and also why do I get linkage error when removing that line?

Upvotes: 2

Views: 316

Answers (3)

Jaka
Jaka

Reputation: 1231

This is specified in C++ standard

9.4.2 Static data members

2 The declaration of a static data member in its class definition is not a definition and may be of an incomplete type other than cv-qualified void. The definition for a static data member shall appear in a namespace scope enclosing the member’s class definition. In the definition at namespace scope, the name of the static data member shall be qualified by its class name using the :: operator. The initializer expression in the definition of a static data member is in the scope of its class

So the declaration in the class scope is not considered a definition, that is why you get the linker error.

Upvotes: 0

Soeren
Soeren

Reputation: 1829

You have to initialize the static variable:

Singleton* Singleton::m_instance = 0;

We can only call static class members on the class and not on an object of the class. And that is possible, even if no instance exist. That's why every static member instance must be initialize, usually in the cpp file.

And because of the static variable is initialized outside the class scope, we have to call the variable by the full name (e.g. Singleton::m_instance).

Upvotes: 2

songyuanyao
songyuanyao

Reputation: 173044

So I dont understand the syntax of that line- why can't I write just Singleton::m_instance = 0;?

The syntax here is the definition of the static member, which need to be defined out of the class definition. That's why if you remove it you'll get the undefined link error.

class X { static int n; }; // declaration (uses 'static')
int X::n = 1;              // definition (does not use 'static')

Upvotes: 0

Related Questions