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

Visual C++ Discussion :

[VC++6.0] Pb de déclaration d'une variable de type template singleton


Sujet :

Visual C++

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Août 2002
    Messages
    225
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 225
    Points : 118
    Points
    118
    Par défaut [VC++6.0] Pb de déclaration d'une variable de type template singleton
    Bonjour à toutes et à tous !

    J'ai récupéré le code source d'une application que je dois optimiser. Il y a quelques variables globales dans cette application et je souhaite mettre à profit le Design Pattern Singleton.

    J'ai récupéré un code source définissant une classe template singleton (.h suivant) :
    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
     
    #ifndef _SINGLETON_H
    #define _SINGLETON_H
     
    template <class T>
    class CSingleton
    {
    	public:
    		// Renvoi l'instance unique de la classe
    		static CSingleton* Instance()
    		{
    			if( !pInst )
    				pInst = new T;
     
    			return pInst;
    		}
     
    		// Détruit l'instance unique de la classe
    		static void Destroy()
    		{
    			delete pInst;
    			pInst = NULL;
    		}
     
    	protected:
    		// Constructeur par défaut
    		CSingleton();
     
    		// Destructeur par défaut
    		~CSingleton();
     
    	private:
    		// Donnée membre
    		static T* pInst;
     
    		// Copie interdite
    		CSingleton(const CSingleton&);
    		void operator=(const CSingleton&);
    };
     
    // Déclaration de notre variable statique
    template <class T> T* CSingleton<T>::pInst = NULL;
     
    #endif
    Jusque la pas de problème , pas de problème de compilation.

    Etape suivante, je souhaite créer mes propres classes dérivant de cette classe template ... hop c'est parti en faisant comme ci après (j'ai juste utilisé un .h) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    #ifndef _UN_SINGLETON_H
    #define _UN_SINGLETON_H
     
    class CUnSingleton : public CSingleton<CUnSingleton>
    {
    	friend class CSingleton<CUnSingleton>;
    };
     
    #endif
    Là encore je compile et aucune erreur

    Mon problème est le suivant : comment déclarer dans mon main une variable de type CUnSingleton ? Quand je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    CSingleton<CUnSingleton>* S = CSingleton<CUnSingleton>::Instance();
    ça passe pas et j'ai le message d'erreur suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    TEMPLATE_SINGLETON.obj : error LNK2001: unresolved external symbol "protected: __thiscall CSingleton<class CUnSingleton>::CSingleton<class CUnSingleton>(void)" (??0?$CSingleton@VCUnSingleton@@@@IAE@XZ)
    Est ce que quelqu'un a une idée à me proposer pour résoudre mon problème ?

    D'avance merci.

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Août 2002
    Messages
    225
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 225
    Points : 118
    Points
    118
    Par défaut
    Information supplémentaire, le code que j'ai repris est celui de Laurent GOMILA et tiré de ses articles sur le développement d'un moteur 3D ... rendons à César ce qui lui appartient.

  3. #3
    Membre habitué
    Inscrit en
    Avril 2002
    Messages
    180
    Détails du profil
    Informations forums :
    Inscription : Avril 2002
    Messages : 180
    Points : 157
    Points
    157
    Par défaut
    pour utilise ont object derive de CSingleton tu peur essaille
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    CUnSingleton& singleton = CUnSingleton::Instance();

  4. #4
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Points : 17 323
    Points
    17 323
    Par défaut
    Citation Envoyé par philippe V
    pour utilise ont object derive de CSingleton tu peur essaille
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    CUnSingleton& singleton = CUnSingleton::Instance();
    plutôt:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    CUnSingleton* psingleton = CUnSingleton::Instance();

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Août 2002
    Messages
    225
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 225
    Points : 118
    Points
    118
    Par défaut
    J'ai essayé ta solution Farscape mais j'obtient l'erreur.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    error C2440: 'initializing' : cannot convert from 'class CSingleton<class CUnSingleton> *' to 'class CUnSingleton *'

  6. #6
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Points : 17 323
    Points
    17 323
    Par défaut
    bon bizarre ,je viens d'essayer ton code (la premiere version)
    ça compil bien sous visual 6.0 et 2005
    la seule difference c'est que pour des raisons de facilité de test j'ai tout mis dans le même source:
    la definition du template, et l'appel à instance.
    tu peux faire un essai dans ce sens ?


  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Août 2002
    Messages
    225
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 225
    Points : 118
    Points
    118
    Par défaut
    Ca compile pour toi ? C'est bizarre ...

    J'ai testé ta proposition en faisant comme suit :
    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
     
    #ifndef _SINGLETON_H
    #define _SINGLETON_H
     
    using namespace std;
     
    template <class T>
    class CSingleton
    {
    	public:
    		// Renvoi l'instance unique de la classe
    		static CSingleton* Instance()
    		{
    			cout << "Appel de la fonction Instance de CSingleton" << endl;
    			if( !pInst )
    			{
    				cout << "Création d'un objet CSingleton" << endl;
    				pInst = new T;
    			}
    			else
    				cout << "L'objet CSingleton est déjà crée" << endl;
     
    			return pInst;
    		}
     
    		// Détruit l'instance unique de la classe
    		static void Destroy()
    		{
    			cout << "Destruction de l'objet CSingleton" << endl;
    			delete pInst;
    			pInst = NULL;
    		}
     
    	protected:
    		// Constructeur par défaut
    		CSingleton();
     
    		// Destructeur par défaut
    		~CSingleton();
     
    	private:
    		// Donnée membre
    		static T* pInst;
     
    		// Copie interdite
    		CSingleton(const CSingleton&);
    		void operator=(const CSingleton&);
    };
     
    // Déclaration de notre variable statique
    template <class T> T* CSingleton<T>::pInst = NULL;
     
    class CUnSingleton : public CSingleton<CUnSingleton>
    {
    	friend class CSingleton<CUnSingleton>;
    };
     
    CUnSingleton* psingleton = CUnSingleton::Instance();
    #endif
    Je n'ai maintenant plus qu'un et un seul header qui se nomme Singleton.h malheureusement j'ai toujours la même erreur.

    J'ai VC++6.0 mais je ne sais pas si le service pack a été installé.

    Je ne vois pas ce que je peux donner d'autre comme informations.

  8. #8
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Points : 17 323
    Points
    17 323
    Par défaut
    non en testant avec:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    CSingleton<CUnSingleton>* S = CSingleton<CUnSingleton>::Instance();

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Août 2002
    Messages
    225
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 225
    Points : 118
    Points
    118
    Par défaut
    J'ai testé toutes les différentes possibilités :
    * tout dans un seul fichier (définition et déclaration)
    * dans des fichiers séparés, déclaration (conforme à ta proposition) dans le main

    maintenant ça compile mais j'ai à nouveau l'erreur d'édition des liens :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    unresolved external symbol "protected: __thiscall CSingleton<class CUnSingleton>::CSingleton<class CUnSingleton>(void)" (??0?$CSingleton@VCUnSingleton@@@@IAE@XZ)

  10. #10
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Points : 17 323
    Points
    17 323
    Par défaut
    arf ,je suis fatigué j'ai mal vu,
    tu as oublié de definir le constructeur protected....
    (attention au destructeur...)
    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
    30
    31
    32
    33
    34
    35
    36
    template <class T>
    class CSingleton
    {
        public:
            // Renvoi l'instance unique de la classe
            static CSingleton* Instance()
            {
                if( !pInst )
                    pInst = new T;
     
                return pInst;
            }
     
            // Détruit l'instance unique de la classe
            static void Destroy()
            {
                delete pInst;
                pInst = NULL;
            }
     
        protected:
            // Constructeur par défaut
            CSingleton(){}
     
            // Destructeur par défaut
            ~CSingleton();
     
        private:
            // Donnée membre
            static T* pInst;
     
            // Copie interdite
            CSingleton(const CSingleton&);
            void operator=(const CSingleton&);
    };
    en gras ci-dessus..

  11. #11
    Membre régulier
    Profil pro
    Inscrit en
    Août 2002
    Messages
    225
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 225
    Points : 118
    Points
    118
    Par défaut
    désolé, je n'ai pas fait attention non plus.

    Au passage, j'ai définit mon destructeur comme virtuel ... ma classe template CSingleton étant destiné à être dérivée, ça se justifie non ?

  12. #12
    Membre régulier
    Profil pro
    Inscrit en
    Août 2002
    Messages
    225
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 225
    Points : 118
    Points
    118
    Par défaut
    Avant d'oublier ...

    je constate que dans le code il y a :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    	private:
    		// Copie interdite
    		CSingleton(const CSingleton&);
    		void operator=(const CSingleton&);
    ça ne pose pas (visiblement puisque la compilation et l'édition des liens sont OK) de ne pas proposer d'implémentation pour ces deux fonctions ?

    J'ai copié collé le code et je ne m'en rend compte que maintenant.

  13. #13
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Points : 17 323
    Points
    17 323
    Par défaut
    ça ne cause pas de probleme tant que tu n'essayes pas d'utiliser le constructeur de copie ou l'operateur d'affectation...

  14. #14
    Membre régulier
    Profil pro
    Inscrit en
    Août 2002
    Messages
    225
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 225
    Points : 118
    Points
    118
    Par défaut
    OK, ça me rassure. En général quand je définit une méthode j'aime assez qu'elle ait une implémentation

    Ta réponse me rassure et m'arrange car je ne voyais pas comment implémenter le constructeur de recopie et l'opérateur d'affectation sachant qu'à priori n'importe quelle classe peut hériter de ce template. De plus une telle implémentation me semblait incompatible avec la notion de Singleton.

    En tout cas merci pour tout. J'essaierai d'être plus vigilant et d'ouvrir un peu plus grand mes yeux la prochaine fois.

    Merci, ++

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

Discussions similaires

  1. [Débutant] Déclaration d'une variable ArrayList
    Par nanath02 dans le forum Collection et Stream
    Réponses: 7
    Dernier message: 08/03/2007, 10h30
  2. Mauvaise déclaration d'une variable
    Par Molos dans le forum Langage
    Réponses: 3
    Dernier message: 21/01/2007, 10h36
  3. Réponses: 7
    Dernier message: 02/08/2006, 15h51
  4. Réponses: 8
    Dernier message: 13/07/2006, 10h04
  5. déclaration d'une variable
    Par ouldfella dans le forum Composants VCL
    Réponses: 8
    Dernier message: 20/10/2005, 18h21

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