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 :

Erreur Factory pattern macro et singleton


Sujet :

C++

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2011
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2011
    Messages : 33
    Points : 27
    Points
    27
    Par défaut Erreur Factory pattern macro et singleton
    Bonjour à tous,

    Voici mon problème en résumé : j'ai une classe Parser, qui est juste un interface (méthodes virtuelles) et une classe ParserPgm par exemple qui hérite de Parser.
    Ensuite j'ai une classe ParserManager qui contient une liste de toutes les classes ParserXXX.
    Le problème actuel que j'ai c'est que quand je rajoute un parser, je dois modifier ParserManager.cpp pour inclure ParserXXX.h et ensuite ajouter à la liste le nouveau type.
    Je me suis donc dit que j'allais créer une macro, à appeler depuis chaque ParserXXX, pour ne pus modifier ParserManager.

    Voilà une simplification de mon code :

    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
     
     
    class Parser:
    {
    public:
     
        Parser() {}    
        virtual ~Parser()  {}
     
        virtual bool open(std::string fileName) const = 0;
        virtual bool save(std::string fileName) const = 0;
    };
     
    class ParserManager:
    {
    public:
     
        static ParserManager *GetInstance() { 
              if (_singleton == NULL)
                 _singleton = new ParserManager();
             return _singleton;
        }
        ~ParserManager() {}
     
         void add(Parser *p) {
             _parsers.add(p);
         }
     
    private:
     
        ParserManager();
        static ParserManager *_singleton;
     
        List<Parser> _parsers;
     
    };
     
    ParserManager *ParserManager::_singleton = NULL;
     
    #define PARSER_MANAGER_REGISTER(TYPE)   ParserManager::GetInstance()->add(new TYPE())
    Et enfin :

    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
     
     
    class ParserXXX:
    {
    public:
     
        ParserXXX() {}    
        virtual ~ParserXXX()  {}
     
        bool open(std::string fileName) const {
           // ...
        }
        bool save(std::string fileName) const {
           // ...
        }
     
    };
     
    #include <ParserManager.h>
    PARSER_MANAGER_REGISTER(ParserQt);
    Et donc j'ai les erreurs suivantes :
    error: expected type-specifier before 'add' ParserManager::Getinstance()->add(new TYPE())
    error: expected constructor, destructor, or type conversion before 'add'

    Voilà, j'espère que j'ai pas été trop long et que je me suis fais comprendre : pour résumer :
    créer une macro pour ajouter dans un singleton différent type type qui hérite d'une base commune.

    Merci de votre aide, cordialement

  2. #2
    Expert confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Points : 4 442
    Points
    4 442
    Par défaut
    Hello,

    Dans ton message d'erreur "Getinstance()" n'a pas de majuscule au "i", faute de frappe dans la macro ?

    Sinon, tes parsers ne sont jamais détruits, attention à ça.

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2011
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2011
    Messages : 33
    Points : 27
    Points
    27
    Par défaut
    Non c'est une erreur de frappe désolé ...
    Pour la destruction, j'ai pas mis tout le code mais c'est bien fait.

    Si je fais en dur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ParserManager::GetInstance()->add(new ParserXXX());
    Cela fait les erreurs suivantes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    error: expected type-specifier before 'add'
    error: expected constructor, destructor, or type conversion before 'add'
    Quelqu'un a une idée ? faut il utiliser le design-pattern Factory ? Comment l'appliquer dans ce cas la ?

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2011
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2011
    Messages : 33
    Points : 27
    Points
    27
    Par défaut
    J'ai trouvé une solution (propre ?, je sais pas) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
     
    // Call in parser class header file
    #define PARSER_REGISTERABLE(TYPE) \
        private: \
        static TYPE *_registeredInstance;
     
    // Call in parser source code file
    #define PARSER_REGISTERABLE_IMPL(TYPE) \
        TYPE *TYPE::_registeredInstance = new TYPE();
     
    // Call parser constructor source code file
    #define PARSER_MANAGER_REGISTER() \
        ParserManager::GetInstance()->add(this);
    Et la classe ParserXXX devient :

    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
     
     
    // Header file
     
    class ParserXXX public Parser:
    {
    PARSER_REGISTERABLE(ParserXXX)
    public:
     
        ParserXXX();
        virtual ~ParserXXX();
     
        bool open(std::string fileName) const;
        bool save(std::string fileName) const;
     
    };
     
    // Source file
     
    PARSER_REGISTERABLE_IMPL(ParserXXX)
     
    ParserXXX::ParserXXX()  :Parser 
    {
        PARSER_MANAGER_REGISTER()
    }    
     
    ParserXXX::~ParserXXX() 
    {}
     
    bool 
    ParserXXX::open(std::string fileName) const {
           // ...
    }
     
    bool 
    ParserXXX::save(std::string fileName) const {
           // ...
    }

  5. #5
    Membre expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Points : 3 156
    Points
    3 156
    Par défaut
    Salut !

    On peut s'en tirer en utilisant l'initialisation statique, voici une technique qui fait quelque chose qui ressemble beaucoup à ce que tu cherches. Attention à ne pas créer le fameux fiasco (le code d'exemple montré ne présente pas ce problème).
    Find me on github

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 116
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 116
    Points : 32 968
    Points
    32 968
    Billets dans le blog
    4
    Par défaut
    Salut,

    Pourquoi les ParserXX ne sont pas de simples singletons ?
    Ca y ressemble beaucoup au final.

    Pourquoi les constructeurs et destructeurs sont public si tu as une factory ? Dangeureux amha..
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  7. #7
    Membre expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Points : 3 156
    Points
    3 156
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Pourquoi les constructeurs et destructeurs sont public si tu as une factory ? Dangeureux amha..
    Attention, il n'y a pas de factory dans le problème de l'auteur du post. Dans mon exemple, la factory sert à faire le lien entre une chaîne de caractère connue à l'exécution et un constructeur, et non pas à forcer la construction par son biais. Il n'y a donc pas lieu de rendre le constructeur privé. Peut être que le terme "Factory" est discutable. Quant à mettre un destructeur privé... là je ne vois pas, une factory n'est jamais faite pour détruire des objets.
    Find me on github

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

Discussions similaires

  1. [Fabrique] factory pattern
    Par SISINE dans le forum Design Patterns
    Réponses: 3
    Dernier message: 28/05/2008, 20h56
  2. Personnalisé Message d'Erreur sur une Macro
    Par faressam dans le forum IHM
    Réponses: 2
    Dernier message: 20/08/2007, 11h40
  3. Réponses: 9
    Dernier message: 18/09/2006, 11h42
  4. [Pattern]PB sur Singleton multi-thread
    Par thibaut dans le forum Général Java
    Réponses: 21
    Dernier message: 11/09/2006, 09h33
  5. message erreur apres efface macro
    Par pat1545 dans le forum Access
    Réponses: 5
    Dernier message: 28/07/2006, 19h45

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