2016-08-02 6 views
0

Ich implementierte eine Singleton-Klasse für mein Spiel, aber jedes Mal, wenn ich versuche, es zu kompilieren, gibt es einen Kompilierungsfehler. Der Code lautet wie folgt:Fehler in Singleton

//Singleton.h 
    #pragma once 

    class Singleton{ 
    public: 
     static Singleton* Instance(); 

    private: 
     Singleton(){}; 

     static Singleton* m_instance; 
    }; 

    Singleton* SingletonInstance = Singleton::Instance(); 

Singleton.cpp

//Singleton.cpp 
#include "Untitled1.h" 

Singleton* m_instance = nullptr; 


Singleton* Singleton::Instance(){ 
    if(m_instance == nullptr){ 
     m_instance = new Singleton; 
    } 
    return m_instance; 
} 

ich die folgenden Fehler bin immer:

 
||=== Build: Debug in df (compiler: GNU GCC Compiler) ===| 
obj\Debug\Untitled1.o||In function `ZN9Singleton8InstanceEv':| 
C:\Users\Samsung R519\Desktop\Untitled1.cpp|7|multiple definition of `SingletonInstance'| 
obj\Debug\main.o:C:\Users\Samsung R519\Desktop\main.cpp|4|first defined here| 
obj\Debug\Untitled1.o:Untitled1.cpp|| undefined reference to `Singleton::m_instance'| 
obj\Debug\Untitled1.o:Untitled1.cpp|| undefined reference to `Singleton::m_instance'| 
||=== Build failed: 4 error(s), 0 warning(s) (0 minute(s), 10 second(s)) ===| 

Was mache ich falsch?

+0

Überdenken Sie (a) warum Sie ein Singleton brauchen: es ist fast immer ein Anti-Pattern; und (b) warum Sie hier Zeiger verwenden. Ein einfaches Objekt mit automatischem Speicher zu verwenden und es als Referenz zurückzugeben, ist fast sicher überlegen, es sei denn, Sie benötigen eine verzögerte Initialisierung. –

+0

Mögliches Duplikat von [Singleton Inheritance Linker Error] (http://stackoverflow.com/questions/7750832/singleton-inheritance-linker-error) – anatolyg

+0

Eine andere (bessere?) Möglichkeit, ein Singleton in C++ zu implementieren: http: // stackoverflow .com/a/1008289/3052438 –

Antwort

3

Es gibt zwei Probleme mit Ihrem Code.

  1. Singleton* SingletonInstance = Singleton::Instance(); Sie sollten die Definition nicht in die Header-Datei einfügen. Stattdessen sollten Sie SingletonInstance in der Kopfzeile deklarieren und in der .cpp-Datei definieren. In der Tat, es gibt keine Notwendigkeit, diese globale Variable zu haben. Sie können immer Singleton::Instance() aufrufen, um das Singleton zu erhalten.

  2. m_instance ist Mitglied der Singleton, so sollten Sie es mit dem Klassennamen definieren: Singleton::m_instance

Die Lösung:

// xxx.h 
// other code... 
extern Singleton* SingletonInstance; // declaration 

// xxx.cpp 
// other code... 
Singleton* Singleton::m_instance = nullptr; // specify the class name 

Singleton* SingletonInstance = Singleton::Instance(); // definition 
3

In der CPP-Datei definieren Sie einen neuen m_instance, der kein Mitglied ist.

Bitte versuchen Sie es

Singleton* Singleton::m_instance = nullptr; 
+0

Es hat funktioniert, aber jetzt kommt dieser Fehler: Singleton.cpp | 7 | Mehrfachdefinition von 'SingletonInstance ' – darkpsychic

1
class Singleton{ 
      .... 
      static Singleton* m_instance; 
    } 

und

Singleton* m_instance = nullptr; 

Sogar wenn den gleichen Namen, sie sind verschiedene Zeiger, weil sie unterschiedliche Bereiche haben: die erste eine Deklaration einer Klasse ist Mitglied und das zweite ist sowohl eine Deklaration als auch eine Definition eines Zeigers im globalen Namespace.

Also, was Sie suchen ist die Definition der Klasse Elementzeiger, das ist:

Singleton* Singleton::m_instance = nullptr; 
1

Ich schlage vor, Sie die Scott Meyers Singleton zu verwenden. Ich werde jeden Fehler vermeiden, der mit der Reihenfolge der Initialisierung und dem Speicherverwaltungsfehler im Zusammenhang mit dem Singleton zusammenhängt.

Hier ist, wie Sie es umsetzen:

struct Singleton { 
    static Singleton& instance() { 
     static Singleton myInstance; 

     return myInstance; 
    } 
}; 

Wenn Sie einen Zeiger anstelle eines Verweises zurückkehren wollen, dies ebenso in Ordnung ist.