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

Langage C++ Discussion :

Création d'une factory. (Problème)


Sujet :

Langage C++

  1. #1
    Invité
    Invité(e)
    Par défaut Création d'une factory. (Problème)
    Bonjour!
    Afin de simplifier mon code source qui est fort complexe et qui en plus me pose des problèmes avec les forwards déclaration.

    J'essaye de créer une factory pour instancier automatiquement des objets d'une classe dérivée, en insérant une fonction non membre dans la classe dérivée qui instancie un objet ainsi qu'une macro ajoute automatiquement cette fonction avec comme nom create suivit de l'id du type de l'objet.
    J'ai aussi besoin d'une autre fonction pour récupérer un pointeur sur la fonction d'instanciation pour instancier l'objet et la passer à la factory.

    Cependant, ceci ne fonctionne pas, malgré que je déclare la fonction dans la macro, lorsque je veux récupérer un pointeur sur cette fonction il me dit que la fonction non membre n'est pas déclarée, voici le code de la macro :

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    #define REGISTER_DERIVED(ID, TYPE) \
    friend TYPE* create##ID() { \
        return new TYPE(); \
    } \
    public : \
    static void getCreateFunc (TYPE*(**func)()) { \
        *func = &create##ID; \
    }
    #define ALLOCATE(TYPE) \
    using TP = typename std::remove_pointer<decltype(TYPE)>::type; \
    TP*(*func)(); \
    TP::getCreateFunc(&func); \
    return (func)();

    Voici ce que je veux faire dans la classe dérivée :

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    REGISTER_DERIVED(BoundingPolyhedron, odfaeg::BoundingPolyhedron)

    Ainsi ça m'ajoute automatiquement les fonctions createBoundingPolyhedron et getCreateFunc dans le fichier boudingPolyhedron.h et je peux allouer ça n'importe ou dans le programme sans plus avoir de problème avec les forwards déclaration.

    Malheureusement ce code me donne une erreur en compilation que je ne comprend pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    /home/laurent/Développement/Projets-c++/ODFAEG/src/odfaeg/Core/../../../include/odfaeg/Core/../Graphics/../Math/../Core/serialization.h|14|error: ‘createBoundingPolyhedron’ was not declared in this scope|
    Pourquoi il me dit que la fonction createBoundingPolyhedron n'existe pas, hors que je l'ai déclarée juste au dessus dans la macro ???

    Merci.

  2. #2
    Invité
    Invité(e)
    Par défaut
    C'est bon j'ai trouvé.

    En fait j'essaye de faire un système de fonction virtuelle template :

    Code cpp : 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
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
     
    #ifndef ODFAEG_SERIALIZATION_HPP
    #define ODFAEG_SERIALIZATION_HPP
    #include <iostream>
    #include <typeinfo>
    #include "tuple.h"
    #include <tuple>
    #include <map>
    #include "fastDelegate.h"
    #define REGISTER_DERIVED(ID, TYPE) \
    TYPE* create##ID() { \
        return new TYPE(); \
    } \
    friend TYPE* create##ID(); \
    public : \
    static void getCreateFunc (TYPE*(**func)()) { \
        TYPE* create##ID(); \
        *func = &create##ID; \
    }
    #define REGISTER_TYPE(typeName, TYPE) \
    using TP = typename std::remove_pointer<decltype(TYPE)>::type; \
    TP*(*func)(); \
    TP::getCreateFunc(&func); \
    register_type(typeName, func);
    #define CALL_FUNCTION(typeID, funcName, TYPE, ARGS...) \
    using TP = typename std::remove_pointer<decltype(TYPE)>::type; \
    TP* derived = dynamic_cast<TP*>(TYPE); \
    derived->vt##funcName(ARGS);
     
    namespace odfaeg {
    template <typename B>
    class BaseFact {
        public :
        template <typename T>
        static void register_type(std::string typeName, T* type) {
            REGISTER_TYPE(typeName, type);
        }
        static void register_type(std::string typeName, B*(*func)()) {
            typename std::map<std::string, B*(*)()>::iterator it = types.find(typeName);
            if (it == types.end())
                types[typeName] = func;
        }
        static B* create (std::string typeName) {
            typename std::map<std::string, B*(*)()>::iterator it = types.find(typeName);
            if (it != types.end())
                return types[typeName]();
            return nullptr;
        }
        static std::string getTypeName (B* type) {
            typename std::map<std::string, B*(*)()>::iterator it = types.find(typeid(type).name());
            if (it == types.end())
                return it->first;
        }
        private :
        static std::map<std::string, B*(*)()> types;
    };
    template <class B>
    class Serializer : public BaseFact<B> {
        public :
        Serializer() {
            baseObject = nullptr;
        }
        void setObject(B* baseObject) {
            this->baseObject = baseObject;
        }
        template <typename Archive>
        void serialize(Archive & ar) {
            CALL_FUNCTION(typeid(*baseObject).name(), serialize, baseObject, ar)
        }
        B* sallocate(std::string typeName) {
            return BaseFact<B>::create(typeName);
        }
        std::string getTypeName() {
            return BaseFact<B>::getTypeName(baseObject);
        }
        private :
        B* baseObject;
    };
    }
    #endif // SERIALIZATION

    Mon code devient donc :

    Code cpp : 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
     
    #ifndef SERIALIZATION_IMPL
    #define SERIALIZATION_IMPL
    #include "serialization.h"
    #define REGISTER_BASE(KEY, TYPE) \
    struct KEY : public Serializer<TYPE> { \
        public : \
        void register_object (TYPE* object) { \
            setObject(object); \
        } \
        TYPE* allocate_object(std::string typeName) { \
            return sallocate(typeName); \
        } \
        std::string getTypeName () { \
            return Serializer<TYPE>::getTypeName(); \
        } \
        template <typename Archive> \
        void serialize_object (Archive & ar) { \
            serialize(ar); \
        } \
    }; \
    public : \
    KEY key; \
    typedef KEY KEYTYPE; \
    virtual void foo() {} \
    static TYPE* allocate (std::string typeName) { \
        static KEY aKey; \
        return aKey.allocate_object(typeName); \
    }
    #endif
    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    #include "../../../include/odfaeg/Core/serialization.h"
    namespace odfaeg {
    template <typename B>
    std::map<std::string, B*(*)(void)> BaseFact<B>::types = std::map<std::string, B*(*)(void)>();
    }

    Et je fais une fonction template dans mes archive pour enregistrer les types dans la factory.

    Mais j'ai des référence indéfinie maintenant. :@ (Vers la std::map)

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

Discussions similaires

  1. Réponses: 11
    Dernier message: 05/08/2009, 12h30
  2. Réponses: 10
    Dernier message: 05/02/2009, 13h22
  3. Création d'une table - Problème....
    Par JoN28fr dans le forum Débuter
    Réponses: 7
    Dernier message: 13/11/2008, 20h27
  4. [ImageMagick] Header envoyé lors de la création d'une image
    Par KLiFF dans le forum Bibliothèques et frameworks
    Réponses: 2
    Dernier message: 25/10/2005, 16h35
  5. Problème de création d'une dll...
    Par adrien954 dans le forum C++Builder
    Réponses: 4
    Dernier message: 21/10/2005, 10h46

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