2010-08-20 5 views
2

Comment créer une instance d'un singleton pouvant être utilisée dans d'autres classes?Utilisation de Singleton dans différentes classes

Par exemple:

//Singleton_Class.h 

#ifndef Singleton_Class 
#define Singleton_Class 

class Singleton 
{ 
private: 
    static Singleton _instance; 

    Singleton() {} 
    ~Singleton() {} 
    Singleton(const Singleton &); 
    Singleton & operator=(const Singleton &); 

public: 
static Singleton &getInstance(){return _instance;} 
}; 

Singleton Singleton::_instance; 

#endif 


//Main.cpp 

#include "Singleton_Class.h" 

int main() 
{ 
    Singleton &s = Singleton::getInstance(); //Use the instance 
} 

//ClassA.cpp 

#include "Singleton_Class.h" 

class A 
{ 
public: 
A(){}; 
}; 

J'obtiens une erreur reliant en essayant d'inclure l'en-tête de classe unique pour la classe A (LNK2005): "private: class statique Singleton Singleton :: _ instance"? (_instance @ Singleton @@ 0V1 @ A) déjà défini dans Singleton Class.obj

Répondre

6

Vous devez définir la variable d'instance dans l'un de vos fichiers sources (.cpp), pas dans le fichier d'en-tête.

Si la variable d'instance est définie dans le fichier d'en-tête, alors lorsque ce fichier d'en-tête est inclus dans plusieurs fichiers source, il finit par être défini plusieurs fois (ce que dit l'erreur).

5

James vous avez déjà dit ce que le problème est: vous devez déplacer la définition de la variable membre static dans son propre fichier .cpp.

Si vous ne voulez pas avoir un fichier .cpp juste pour la variable, vous pouvez faire une static locale à la fonction getInstance():

class Singleton 
{ 
private: 
    Singleton() {} 
    ~Singleton() {} 
    Singleton(const Singleton &); 
    Singleton & operator=(const Singleton &); 

public: 
    static Singleton &getInstance() 
    { 
    static Singleton _instance; 
    return _instance; 
    } 
}; 

Cela signifie que l'initialisation paresseuse, cependant. Habituellement c'est OK, mais parfois vous avez besoin de l'objet à initialiser avant .

Si vous avez ce problème, vous pourriez peut-être mettre la variable d'instance dans un modèle de classe:

// Beware, brain-compiled code ahead! 
template< typename S > 
class SingletonBase 
{ 
private: 
    friend class Singleton; 
    SingletonBase() {} 
public: 
    static S instance; 
}; 

template< typename S > 
S SingletonBase<S>::instance; 

class Singleton : private SingletonBase<Singleton> 
{ 
private: 
    Singleton() {} 
    ~Singleton() {} 
    Singleton(const Singleton &); 
    Singleton & operator=(const Singleton &); 

public: 
    static Singleton &getInstance(){return instance;} 
}; 
Questions connexes