2017-01-31 2 views
2

Ich versuche die Bedeutung des Fehlers zu verstehen, den ich bekomme.Singleton-Verbindungsfehler

dies ist eine Singleton Implementierung:

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(); 
} 

Die Code colpiles und laufen sucessfuly.

Wenn ich die Linie Singleton* Singleton::m_instance = 0; entfernen, erhalte ich die Fehlermeldung:

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

Ich denke, die Bedeutung dieser Linie ist die statische Variable m_instance auf 0

So setzen nicht, daß ich die Syntax verstehen von dieser Linie - warum kann ich nicht nur Singleton::m_instance = 0; schreiben? und warum bekomme ich Linkfehler beim Entfernen dieser Zeile?

+0

Der bessere idiomatische Weg: http://stackoverflow.com/questions/1008019/c-singleton-design-pattern –

Antwort

0

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

Die Syntax ist hier die Definition des static member, die aus der Klassendefinition definiert werden müssen. Wenn Sie es entfernen, erhalten Sie den undefinierten Verbindungsfehler.

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

Sie haben die statische Variable zu initialisieren:

Singleton* Singleton::m_instance = 0; 

Wir können nur statische Klassenmitglieder auf der Klasse aufrufen und nicht auf ein Objekt der Klasse. Und das ist möglich, auch wenn keine Instanz existiert. Deshalb muss jede statische Memberinstanz initialisiert werden, normalerweise in der cpp-Datei.

Und da die statische Variable außerhalb des Klassenbereichs initialisiert wird, müssen wir die Variable mit dem vollständigen Namen aufrufen (z. B. Singleton :: m_instance).

0

Dies ist in C++ angegeben 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 wird die Deklaration in dem Klassenbereich eine Definition nicht berücksichtigt, weshalb Sie die Linker Fehler.