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 :

Réflexion, templates et essai


Sujet :

C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2008
    Messages : 31
    Par défaut Réflexion, templates et essai
    Bonjour à tous,

    Je me suis "amusé" à tenter de faire de la "réflexion" en c++, c'est à dire manipuler des objets à partir d'un ensemble d'objets... pas très clair mais bon.

    Seulement, il faut manipuler les templates à tout va, je me retrouve rapidement avec un code dégelasse.

    Dans mon code, il y a plusieurs problèmes.

    • l'énorme répétition du code pour l'enregistrement des méthodes.
      en effet, il faut une classe pour "sans paramètre", une classe pour "1 paramètre", une classe pour "2 paramètres"... et on double ça pour gérer le cas où le type de retour est void. D'où la première question comment simplifier ça ? (fichier methods.h)

    • Le trop gros nombre de "reinterpret_cast<>", j'ai l'impression que ça pourri mon code, est-ce que vous voyiez un moyen de les virer?

    • Le fait que les types soit intransigeants, c'est à dire que si votre méthode à un paramètre de type int et que vous envoyiez un double, ça va pas marcher, il n'y aura pas de cast implicite. C'est dû aux reinterpret_cast<>, raison de plus de les faire disparaître.

    • Pour enregistrer une méthode, je dois spécifier si un paramètre est une référence ou un pointeur. Je créer donc une liste de "Policies".
      J'ai vu que typeid(T).name() renvoie une chaine avec toutes ces infos (type, référence/valeur/pointeur,..). C'est portable, ça vaut le coup de faire un parseur pour gérer ça automatiquement ?


    Pour donner un avant goût, voici ce que fait mon code (la partie intéressante est dans le main, en bas)

    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
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
     
    #include "objectregister.h"
    using namespace std;
     
     
    /*
        Objet pour l'exemple
    */
    class MyRootObject{
        public :
            void show(){
                std::cout<<"I am the root."<<std::endl;
            }
    };
     
    /*
        Objet pour l'exemple
        Manipule un entier
    */
    class MyObject : public MyRootObject{
     
        int t;
     
        public:
     
            MyObject():t(10){}
     
            void set(int& n){
                t = n;
                n = 2 * n + 2; //pour tester si le passage par référence marche
            }
            int get(){
                return t;
            }
            void show(){
                std::cout<< "show" << " : " << t <<std::endl;
            }
    };
     
    int main()
    {
        Object<MyRootObject> myRootObject("MyRootObject");//on déclare l'objet
        myRootObject.method("show",&MyRootObject::show);//on déclare sa methode show
     
        Object<MyObject> myObject("MyObject"); //on déclare l'objet MyObject
        myObject.extends(&myRootObject); //qui dérive de MyRootObject, on doit le lui dire
        myObject.method("set",&MyObject::set,arg(1,ref)); //on enregistre la méthode, le premier argument est une référence
        myObject.method("get",&MyObject::get);
        //myObject.method("show",&MyObject::show);  //Si cette méthode n'est pas déclaré, la méthode parent sera appelée
                                                    //Si on met la méthode show de MyRootObject "virtual" alors c'est celle de
                                                    //MyObject qui sera appelée (logique).
                                                    //Si on la déclare, c'est celle-là qui sera appelée
     
        MyObject* obj = myObject.construct();//pour l'instant ne support que la construction sans paramètre
     
        std::cout << myObject.call<int>(obj,"get") << std::endl; //on appelle la méthode get de l'objet crée, et on affiche le retour
     
        ParamList params; //une liste de paramètres
        Policies police = myObject.getPolicies("set");//les "polices" de la méthode (pour savoir si c'est une méthode, un pointeur,..)
     
        int val = 6;
        params.add(val,police[1]);  //on ajoute à la liste. police[1] où 1 est le premier paramètre voir déclaration de MyObject::set
                                    //Note : 0 -> la valeur de retour
     
        myObject.call(obj,"set",&params);//on appelle la fonction avec les paramètre
        myObject.call(obj,"show");//on affiche la nouvelle valeur de obj, graçe à une fonction interne.
        std::cout << val << std::endl;//on se rappelle que set modifie la valeur d'entrée, on vérifie que ça marche bien.
        params.deleteAll(); //nom temporaire, permet de vider ParamList, pour une prochaine utilisation.
                            //Est aussi appelé dans le destructeur, donc il n'y en aurait pas besoin ici, mais c'est pour l'exemple.
     
        return 0;
    }
    Voilà, si vous pouviez me dire ce que vous pensez du code ainsi que répondre à mes questions, ça serait super


    Voici les fichiers pour tester :
    Fichiers attachés Fichiers attachés

  2. #2
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Par défaut
    Regarde le code source de CAMP pour te donner une idée d'une manière de procéder. Et si laurent passe par là, il y a moyen qu'il te donne son avis vu que c'est son code
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  3. #3
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par défaut
    Selon moi, c'est un code qui devrait être écrit pas un pré-compilateur, et pas à la main. D'une part parce que généralement, le code gérant ce type de fonctionnalité est assez touffu, et d'autre part parce que la maintenance n'en est pas simple (j'ai ajouté une méthode, mais j'ai oublié de la documenter). gcc permet de greffer un plugin sur le compilateur, ou d'utiliser un plugin existant (gcc-xml est particulièrement adapté). Même si les sources sont construits avec un autre compilateur, on peut envisager d'utiliser gcc pour générer l'AST qui sera ensuite parsé et transformé en code C++ de reflexion. Ensuite, une librairie comme CLAMP peut être utilisée pour écrire le code véritable.

    En ce qui concerne la répétition du code, C++0x devrait simplifier pas mal de choses grâce aux variadic templates.
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  4. #4
    screetch
    Invité(e)
    Par défaut
    je pense comme manu (tu permets hein? c'est un peu long emmanuel )
    avec ma bibliothèque RTTI j'ai implémenté un script python qui parse le code C++ et génère un fichier C++ pour le RTTI.
    je me suis rendu compte que Panda3D utilise un système similaire, et c'est bien car ils peuvent maintenir leur langage de script a jour automatiquement (leur outil n'est pas en python mais c'est sur le même principe)

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2008
    Messages : 31
    Par défaut
    Merci pour vos réponses.

    Le problème n'est pas tant l'utilité de la chose (enfin si mais bon), mais surtout comment ça marche en fait.

    Effectivement, je n'avais pas pensé aux plug-in pour gcc, mais je préfère un truc qui marche plus ou moins sous n'importe quel compilo, qui agit comme une bibliothèque et dont on peut choisir quoi définir ou pas.

    merci, je vais regarder pour les variadic template.

    Du coup ça ne répond pas vraiment à mes questions qui sont plutôt là pour me permettre de comprendre comment ça marche. Effectivement si je veux vraiment utiliser un truc comme ça, je préfèrerais CAMP .

Discussions similaires

  1. [Templates] Quel système utilisez-vous ? Pourquoi ?
    Par narmataru dans le forum Bibliothèques et frameworks
    Réponses: 270
    Dernier message: 26/03/2011, 00h15
  2. Template XHTML
    Par Sylvain James dans le forum XSL/XSLT/XPATH
    Réponses: 14
    Dernier message: 16/06/2003, 21h45
  3. appliquer plusieurs templates
    Par Manu_Just dans le forum XSL/XSLT/XPATH
    Réponses: 7
    Dernier message: 04/04/2003, 16h26
  4. template match="node() mais pas text()"
    Par Manu_Just dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 26/03/2003, 10h52
  5. [XSLT] template
    Par demo dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 09/09/2002, 11h31

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