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 :

typedef c'est pas pour les variables mais pour les types


Sujet :

C++

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 11
    Points : 9
    Points
    9
    Par défaut typedef c'est pas pour les variables mais pour les types
    Bonjour !

    J'ai un petit souci

    Je vous explique.

    J'ai une structure ( singleton ) inclut dans un namespace avec un pointeur définit en externe.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Design.hpp
     
    namespace Design
    {
     
         struct Data : public Singleton< Data >
         {
              // données
         } ;
     
     
    extern Data * TheData ;
     
    } // namespace Design
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Design.cpp
     
    #include "Design.hpp"
     
    Design::Data * Design::TheData = nullptr ;
     
    // etc
    Dans une fonction en dehors du namespace "Design" j'utilise le pointeur "TheData" .

    Je voulais savoir si au lieu de taper :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    using namespace Design ;
     
    TheData->Truc ;
    ou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Design::TheData->Truc ;
    je peux utiliser un typedef ?

    J'ai évidemment essayé mais le compilateur ( Visual C++ 2008 )dit qu'il y a

    une erreur de syntaxe( error C2649 ).

    Voilà ce que j'ai essayé

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    1 : typedef Design::TheData data ;
     
    2 : typedef Design::TheData * data ;
     
    3 : typedef Design::Data * Design::TheData data ;
     
    4 : typedef struct Design::TheData data ;
     
    5 : typedef struct Design::TheData * data ;
     
    // etc
    En gros, je ne trouve pas la syntaxe correcte.

    Je sais que ce que je désire faire est discutable, les premières solution sont suffisament correctes.

    Mais je suis curieux .

    Quelqu'un pourrait-il m'aider ?

    Merci !

  2. #2
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Bonjour et bienvenu,
    un typedef, c'est sur le type. Ca ne peut pas te faire un synonyme sur une variable.
    Pour cela il faudrait utiliser une référence :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
       Design::Data*& pt_synonyme = Design::TheData; // sur le pointeur
       Design::Data& synonyme = *Design::TheData; // sur sa valeur

  3. #3
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    A vrai dire, tu te trompes completement dans l'utilisation de ton singleton...

    L'idée est de partir sur une forme proche de
    fichier d'en-tête (monSingleton.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
    class MonSingleton
    {
        public:
            MonSingleton & /* ou * */ instance()
            {
                /* solution 1: pas de membre statique de la classe */
               static MonSingleton ret;
               return ret // uniquement avec renvoi d'une référence 
               /* solution 2: utilisation d'un membre statique de la classe */
               if(! inst)
                   inst=new MonSingleton;
               return *inst; // si renvoi d'une référence
               return inst; // si renvoi d'un pointeur
            }
            /* fonctions membres non statiques */
        private:
            MonSingleton(){}
            ~MonSingleton(){}
            /* uniquement pour la solution 2 */
            static MonSingleton * inst;
     
    }
    fichier d'implémentation (monSingleton.cpp)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MonSingleton * MonSingleton::inst = NULL
    et, chaque fois que tu as besoin de ton singleton, travailler sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MonSingleton::instance().laFonctionMembreQuiTInteresse(/* arguments éventuels */ );
    Voire, si tu prévois d'avoir plusieurs singletons, de centraliser les comportements propres au singleton (le fait passer par la fonction membre statique instance() ) dans une classe template (pour que chaque singleton puisse vivre indépendamment des autres) sous une forme proche de
    fichier d'en-tête (TSingleton.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
     
    template <class T>
    class TSingleton
    {
     
        public:
            TSingleton & /* ou * */ instance()
            {
                /* solution 1: pas de membre statique de la classe */
               static TSingleton ret;
               return ret // uniquement avec renvoi d'une référence 
               /* solution 2: utilisation d'un membre statique de la classe */
               if(! inst)
                   inst=new T;
               return *inst; // si renvoi d'une référence
               return inst; // si renvoi d'un pointeur
            }
            /* fonctions membres non statiques */
        protected:
            MonSingleton(){}
            ~MonSingleton(){}
        private:
            /* uniquement pour la solution 2 */
            static T * inst;
     
    };
    template class T>
    T * TSingleton<T>::inst = NULL;
    dont l'utilisation utilisera le CRTP sous une forme proche de
    #include <TSingleton.h>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class MonSingleton : public TSingleton<MonSingleton>
    {
        friend class TSingleton<MonSingleton>;
        public:
            /* les fonctions membres intéressantes */
        private:
            MonSingleton(){}
            ~MonSingleton(){}
    };
    mais qui sera utilisé de manière exactement similaire.
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  4. #4
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 11
    Points : 9
    Points
    9
    Par défaut
    Salut ,

    Merci à vous pour vos réponses claires et précises

    3DArchi :

    J'ai désormais compris l'utilisation des typedef.

    Je vais donc utiliser cette syntaxe :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Design::Data& synonyme = *Design::TheData ;
    koala01 :

    Merci pour ton explication !

    J'utilise un moteur de jeu ( C4Engine, un peu de pub ).

    Dans lequel une classe Singleton est déjà implémentée.

    La license ne me permet pas de divulguer le code.....

    je fait :

    pour créer l'instance.

    et je détruit le pointeur global pour la détruire.

    Le code du constructeur est le suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Design.cpp
     
    #include "Design.hpp"
     
    Design::Data * Design::TheData = nullptr ;
     
    Design::Data::Data( void ) : public C4::Singleton< Data >( TheData )
    {      }
    Ce doit être un modéle connu...

    Il est vrai que rien ne m'empêche, de créer une autre classe Singleton, qui me

    renverrait directement une référence sur l'instance, je vais y penser et m'y

    atteler, si le besoin se fait sentir.


  5. #5
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    En fait, tout semble indiquer que la classe template C4::Singleton présente une forme proche de la deuxième que j'ai présentée...


    [EDIT]Tu devrais donc vérifier la présence d'une fonction déclarée statique renvoyant un pointeur vers le type d'argument template et, vraisemblablement nommée instance (ou similaire) [/EDIT]

    De ce fait, tu devrais, idéalement, définir le constructeur et le destructeur en accessibilité privée et déclarer le type C4::Singleton<Data> amie de ta classe Data.

    Attention, je parle bien de les définir, c'est à dire de les déclarer et de leur donner un corps

    Le but est double:
    En rendant ces deux fonctions particulières privées (mais en le faisant exister quand même),
    1. tu t'assure que personne (hormis la classe... Singleton au travers de sa fonction membre instance ou similaire) ne sera en mesure de créer une autre instance de l'objet
    2. En rendant le destructeur privé (mais en le faisant exister quand même), tu t'assure que personne (hormis la classe... Singleton au travers d'une éventuelle fonction destroy ou similaire, si elle existe) ne pourra décider de détruire l'instance unique lorsqu'elle existe.


    En effet, en l'état actuel, tel que tu utilise ta classe data, tu n'a absolument pas de certitude que ta classe n'existe que sous la forme d'une instance unique.

    Qu'il te suffise d'écrir un code aussi simple que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include <Data.h>
    int main()
    {
        Desing::Data * ptr1=new Desing::Data;
        Desing::Data * ptr2=new Desing::Data;
        std::cout<<"Adresse de ptr1 : "<<ptr1<<std::endl
                 <<"Adresse de ptr2 : "<<ptr2<<std::endl;
        delete ptr1;
        delete ptr2;
        return 0;
    }
    Si, vraiment, ta classe Data était un singleton, les deux adresses devraient être identiques, vu que c'est le but d'un singleton.

    Or, je suis près à parier mon caleçon que tu obtiendra une sortie indiquant deux adresses différentes
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  6. #6
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 11
    Points : 9
    Points
    9
    Par défaut
    Hello koala01,

    Citation Envoyé par koala01
    Tu devrais donc vérifier la présence d'une fonction déclarée statique renvoyant un pointeur vers le type d'argument template et, vraisemblablement nommée instance (ou similaire)
    En fait, il n'y a qu'un constructeur et un destructeur en accés protégé .

    J'accède à la classe grâce au pointeur global. Donc il n'y a pas ce genre de fonction.

    Citation Envoyé par koala01
    En fait, tout semble indiquer que la classe template C4::Singleton présente une forme proche de la deuxième que j'ai présentée...
    En effet.

    Citation Envoyé par koala01
    En effet, en l'état actuel, tel que tu utilise ta classe data, tu n'a absolument pas de certitude que ta classe n'existe que sous la forme d'une instance unique.
    Je ne peux créer qu'une instance, car le constructeur du singleton ne prend qu'un pointeur en paramètre.

    En cherchant bien ce modéle doit bien avoir une faille mais encore faut-il
    vouloir l'exploiter

    A plus !

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 30/05/2012, 19h43
  2. L'erreur n'est pas dans le code mais où ?
    Par Invité dans le forum Langage
    Réponses: 6
    Dernier message: 04/05/2009, 15h43
  3. Réponses: 2
    Dernier message: 17/04/2008, 14h27
  4. Réponses: 14
    Dernier message: 31/05/2007, 11h04

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