IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

error LNK2001 avec singleton


Sujet :

C++

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 16
    Points : 11
    Points
    11
    Par défaut error LNK2001 avec singleton
    salut,
    je cherche à définir une classe CConsole, héritée d'une classe template CSingleton, et utilisée alors dans une classe CTest mais j'obtiens une erreur au linkage :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    test.obj : error LNK2001: unresolved external symbol "private: __thiscall CConsole::CConsole(void)"
    voici le code du fichier console.h :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    #ifndef CONSOLE_H
    #define CONSOLE_H
     
    #include "singleton.h"
     
    class CConsole : public CSingleton<CConsole> {
    friend class CSingleton<CConsole>;
     
    public:
     
    protected:
     
    private:
       CConsole(void);
       ~CConsole(void);
    };
     
    #endif
    le code de singleton.h :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    #ifndef SINGLETON_H
    #define SINGLETON_H
     
    template <class T>
    class CSingleton {
    public:
       static T *get(void);
     
    protected:
     
    private:
       CSingleton(void);
       ~CSingleton(void);
     
       static T *m_pInst;
    };
     
    template <class T> T *CSingleton<T>::m_pInst=NULL;
     
    template <class T>
    T *CSingleton<T>::get(void) {
       if(m_pInst == NULL) {
          m_pInst=new T();
       }
     
       return m_pInst;
    }
     
    #endif
    et le code pour tester :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #include "console.h"
    [...]
    CConsole *pConsole=CConsole::get();
    j'ai trouvé que ça marchait si :
    - je ne fais pas d'objet CConsole dans CTest, mais bon y a aucun intérêt puisque c'est mon objectif,
    - et si je commente la ligne "CSingleton(void);" dans singleton.h
    je ne comprends pas pourquoi et ça ne me semble pas être correct donc je viens ici vous demander de l'aide.
    je précise que le test est effectué dans un projet de dll, si ça a son importance dans cette erreur.
    par avance, merci

  2. #2
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Ben... Est-ce que tu as écrit un corps pour le constructeur de ta classe CConsole ?

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 16
    Points : 11
    Points
    11
    Par défaut
    non j'en ai pas encore eu besoin.
    c'est nécessaire pour pouvoir instancier une classe ?

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 382
    Points : 41 590
    Points
    41 590
    Par défaut
    en tout cas, c'est nécessaire pour compiler, puisque le linker se plaint qu'il ne le trouve pas (il a beau être privé, s'il est déclaré et pas défini, c'est pas top... Donne-lui un corps vide, à ton constructeur, mais un corps quand même)

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 16
    Points : 11
    Points
    11
    Par défaut
    ok. mais ça me retourne une erreur du compilateur :

    error C2248: 'CSingleton<class CConsole>::CSingleton<class CConsole>' : cannot access private member declared in class 'CSingleton<class CConsole>'
    qu'est-ce qui ne va pas dans mon code ?
    je ne peux donc pas exporter la class CTest de la DLL ?

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 16
    Points : 11
    Points
    11
    Par défaut
    ouf ! j'ai trouvé ce qui n'allait pas :
    1/ j'ai changer la visibilité du constructeur et du destructeur de la classe CSingleton :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    protected: // avant: public
       CSingleton(void);
       virtual ~CSingleton(void); // ajout de "virtual"
    2/ j'ai ajouter les corps vides des constructeurs et destructeurs des classes CSingleton et CConsole.
    est-ce que ça vous paraît logique pour la classe CSingleton ?

    3/ accessoirement j'ai rajouter virtual devant la déclaration du destructeur de CSingleton.

  7. #7
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    1/ j'ai changer la visibilité du constructeur et du destructeur de la classe CSingleton :
    Les classes filles de CSingleton ayant besoin d'appeler son constructeur et son destructeur, effectivement c'est nécessaire.

    2/ j'ai ajouter les corps vides des constructeurs et destructeurs des classes CSingleton et CConsole.
    est-ce que ça vous paraît logique pour la classe CSingleton ?
    A partir du moment où ils vont être appelés, oui c'est encore une fois nécessaire.

    3/ accessoirement j'ai rajouter virtual devant la déclaration du destructeur de CSingleton.
    Cela va ajouter des données inutiles à ta classe (ie. une v-table). Inutile car tu ne vas jamais détruire une instance de singleton à partir d'un pointeur sur la classe de base.

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 16
    Points : 11
    Points
    11
    Par défaut
    Cela va ajouter des données inutiles à ta classe (ie. une v-table). Inutile car tu ne vas jamais détruire une instance de singleton à partir d'un pointeur sur la classe de base.
    ok, vu comme ça, ça me parle un peu plus. j'avais vu faire ça et en me renseignant sur le mot clé virtual j'avais pas trouvé que c'était une si mauvaise idée, mais je n'avais pas trop réfléchit non plus. j'me rends compte que tu as raison, enfin, je partage ton avis. c'est des notions nouvelles pour moi.

    merci loulou pour tes réponses.
    j'ajoute que j'ai pas mal de fois parcourru ton code "Yes" qui me semble, pour mon niveau, très très chaud à suivre. je l'ai d'ailleurs à portée de click sur le bureau où j'ai jeter un oeil pour ta classe singleton, mais on a 2 façon assez distinctes d'approcher notre implémentation ^^
    voilà, j'voulais te le dire.

    hum, qu'est-ce qu'une "v-table" ? s'il te plaît.

  9. #9
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    C'est la table virtuelle, qui est créée pour toute classe possédant au moins une fonction membre virtuelle, et permettant de faire les liaisons dynamiques à l'execution.

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 16
    Points : 11
    Points
    11
    Par défaut
    ok, merci pour cette information. je vais le retirer tout de suite ^^

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 10/06/2008, 10h22
  2. error LNK2001 avec Omni Sensable
    Par vialou dans le forum Visual C++
    Réponses: 2
    Dernier message: 26/02/2008, 15h40
  3. debutant: erreur LNK2001 avec la librairie GSL
    Par drill3 dans le forum MFC
    Réponses: 6
    Dernier message: 25/04/2005, 14h58
  4. Réponses: 4
    Dernier message: 24/03/2004, 13h37
  5. [Kylix] Runtime error 230 avec INDY
    Par Anonymous dans le forum EDI
    Réponses: 2
    Dernier message: 23/03/2002, 12h51

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo