2009-07-14 7 views
2

Je reçois un message d'erreur de référence non définie, sur cette déclaration:référence non définie - C++ erreur de liens

GlobalClass *GlobalClass::s_instance = 0; 

Toutes les idées? Code est présenté ci-dessous:

========================================= =======

#ifndef GLOBALCLASS_H_ 
#define GLOBALCLASS_H_ 

#include <string> 
class GlobalClass { 

public: 

    std::string get_value(); 

    void set_value(std::string); 

    static GlobalClass *instance(); 

    static GlobalClass *s_instance; 

private: 

    std::string m_value; 
}; 

#endif /* GLOBALCLASS_H_ */ 

==================================== ===========

#include <string> 
#include "GlobalClass.h" 



/* 
GlobalClass(int v = 0) 
{ 
m_value = v; 
} 
*/ 

    static GlobalClass *s_instance; 

    std::string GlobalClass::get_value() 
    { 
     return m_value; 
    } 

    void GlobalClass::set_value(std::string v) 
    { 
     m_value = v; 
    } 

    static GlobalClass *instance() { 
     if (!s_instance) 
      s_instance = new GlobalClass; 
     return s_instance; 
    } 

================================ ===========================

#include <iostream> 
#include "GlobalClass.h" 

using namespace std; 

int main() { 

    GlobalClass::s_instance = 0; 


    std::string myAddress = "abc"; 
    GlobalClass::instance()->set_value(myAddress); \\ <=== compiler error 
    std::cout << "====>address is is " << GlobalClass::instance()->get_value() 
      << std::endl; 
    return 0; 
} 
+1

Vous avez deux définitions GlobalClass, une sans s_instance ... Cela pourrait-il être source de confusion? – Eli

+0

Doh, j'ai copié le mauvais fichier - merci. –

+0

Vous continuez d'éditer le corps.Est-ce l'erreur avec 'GlobalClass :: instance() -> set_value (myAddress)' ou avec 'GlobalClass * GlobalClass :: s_instance = 0;'? Ce n'est pas clair. –

Répondre

4

Essayez-vous d'implémenter une classe Singleton? C'est à dire. Vous ne voulez qu'une seule instance de la classe et vous souhaitez que cette instance soit disponible pour tous les utilisateurs de la classe. Je pense que communément appelé Singleton, l'exemple suivant fonctionne comme prévu:

Singleton.h:

#include <string> 
class Singleton 
{ 
public: 
    static Singleton* instance() 
    { 
     if (p_theInstance == 0) 
      p_theInstance = new Singleton; 
     return p_theInstance; 
    } 
    void setMember(const std::string& some_string) 
    { 
     some_member = some_string; 
    } 
    const std::string& get_member() const 
    { 
     return some_member; 
    } 

private: 
    Singleton() {} 
    static Singleton* p_theInstance; 
    std::string some_member; 
}; 

Singleton.cpp:

Singleton* Singleton::p_theInstance = 0; 

main.cpp:

#include <string> 
#include <iostream> 
#include "Singleton.h" 

int main() 
{ 
    std::string some_string = "Singleton class"; 
    Singleton::instance()->setMember(some_string); 
    std::cout << Singleton::instance()->get_member() << "\n"; 
} 

Notez que le constructeur est privé, nous ne voulons pas que quiconque crée des instances de notre singleton, u à moins que ce soit via l'opérateur 'instance()'.

+0

Pourquoi le fichier d'en-tête a-t-il les définitions des méthodes en leur sein? –

+0

Il ne doit pas, vous pouvez les mettre dans le. Cpp, qui était moi paresseux et ne voulant pas les écrire là-bas. Cependant, le code ci-dessus est toujours valide, et je l'ai compilé et testé. – DeusAduro

+0

Je l'ai essayé, et si j'ajoute "include Singleton.h" dans Singleton.cpp, il compile et s'exécute. Je vais le mettre dans le projet principal et voir si ça marche. Merci! –

0

Si je comprends ce que vous voulez faire est seulement une question de USI ng this:

GlobalClass::s_instance = 0; 
+0

Oui, merci, ça m'a permis de dépasser celui-là. J'ai republié avec le prochain ... –

3

Lorsque vous déclarez un champ statique s_instance dans votre fichier .h, il indique seulement au compilateur que ce champ existe quelque part. Ceci permet à votre main de le référencer. Cependant, il ne définit aucun champ, c'est-à-dire qu'aucune mémoire ne lui est réservée et aucune valeur initiale ne lui est affectée. Ceci est analogue à la différence entre un prototype de fonction (généralement dans un fichier .h) et une définition de fonction (dans un fichier .cpp).

Afin de définir réellement le champ, vous devez ajouter la ligne suivante dans votre fichier .cpp à portée globale (pas à l'intérieur de fonction):

GlobalClass* GlobalClass::s_instance = 0; 

Il est important que vous n'ajoutez pas le modificateur static à cette définition (bien que vous devriez toujours avoir le modificateur static sur la déclaration dans la classe dans le fichier .h). Lorsqu'une définition en dehors d'une classe est marquée static, cette définition peut uniquement être utilisée dans le même fichier .cpp. L'éditeur de liens agira comme s'il n'existait pas s'il était utilisé dans d'autres fichiers .cpp. Cette signification de static est différente de static à l'intérieur d'une classe et de static à l'intérieur d'une fonction. Je ne sais pas pourquoi les concepteurs de langage ont utilisé le même mot-clé pour trois choses différentes, mais c'est comme ça.

+0

Jay, j'ai fait comme vous l'avez suggéré, l'explication est logique. Malheureusement, je reçois toujours la même erreur de lien sur les deux références restantes aller GlobalClass dans le principal ... –

+0

merci jay, oui, dois déclarer la propriété statique dans le fichier cpp aussi – jondinham