Hello,
Dans une fonction, je reçois sous forme de chaîne le nom d'une classe.
Comment, muni de cette chaîne de caractère, puis-je référencer les membres de cette classe ?
Je précise que cela doit également être compilable sous gcc...
Merci.
Hello,
Dans une fonction, je reçois sous forme de chaîne le nom d'une classe.
Comment, muni de cette chaîne de caractère, puis-je référencer les membres de cette classe ?
Je précise que cela doit également être compilable sous gcc...
Merci.
Il n'y a pas moyen en C++ mais différentes techniques permettent de contourner le problème. Le choix dépend de ce que les classes ont en commun et du contexte.
Pour le contexte, c'est simple : une fonction reçoit en paramètre le nom d'une classe, et elle appelle une autre fonction ayant en paramètre des accès à cette classe.
Les classes n'ont pas forcément grand chose en commun.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 fonction_A("nom de classe") { fonction_B(classe::pouet); }
Tu peux te renseigner sur ce que fait CRuntimeClass(MFC), ou bien le pattern Factory tel qu'il est employé dans Tclcl...
Par contre, selon le compilateur, il peut y avoir certains problèmes, comme ceux indiqués ici:
http://www.developpez.net/forums/sho...d.php?t=222397
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
Ca me paraît aller trop loin, cette histoire... :-/
Mais j'en profite pour retourner le problème : est-il possible, à partir d'une classe, de récupérer son nom sous forme de chaîne ?
Et dans ce cas, comment passer en paramètre une référence à cette classe sans qu'il n'y ait d'instanciation, juste histoire de récupérer son nom sous forme de chaîne, ET d'appeler des méthodes statiques ?
a- non.Envoyé par oodini
Avec GCC, via les typeinfo, tu auras un nom de classe parasité par les infos de décorations nécessaires au link. Il te faudra faire appel à un demangleur.
Il y a une lib avec GCC pour faire cela. Elle est bien cachée, mais elle existe.
b- Il te te faut définir quelque chose d'équivalent dans le principe à une factory. En fait, si les createurs sont paramétrables (pour utiliser autre chose que "new T()"), il est même possible d'utiliser une factory générique.
Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...
OK, merci pour ces infos pointues.
Je crois que je vais renoncer à l'idée de factoriser, et me taper des redites dans mon code...
À ta question a), on peut répondre oui et non.
Non de base, mais oui très facilement, en implémentant une RTTI (Run-Time Type Identification) de ton cru. C'est ce que fait MFC avec ses CRuntimeClass, et de ce coté-ci, il n'y a aucun problème, car depuis un objet, il est très facile d'avoir accès à sa CRuntimeClass (le problème évoqué plus haut se posait dès qu'une collection était nécessaire, par exemple pour récupérer la CRuntimeClass à partir d'une chaîne).
Par contre, pour ton coup des méthodes statiques, j'ai bien peur que qu'il y ait une faille quelque part dans ta conception, puisqu'une méthode statique est par définition non-virtuelle, donc n'est pas supposée dépendre du type.
Il te faudrait donc au minimum un pointeur vers une "interface"...
Edit: Enfin, tu peux toujours associer à ta CRuntimeClass (ou ton équivalent) une série de pointeurs de fonctions pointant vers diverses méthodes statiques de la classe...
C'est ce que fait IMPLEMENT_DYNCREATE() de MFC qui donne un pointeur vers la fonction CMaClasse::Create() qui appelle le constructeur...
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
Voici un bout de code qui fait du demangling sous gcc, et qui utilise directement typeid pour les autres.Envoyé par oodini
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 #if __GNUC__ > 3 || ( __GNUC__ == 3 && __GNUC_MINOR__ > 0 ) #define GCC_USEDEMANGLE #endif #ifdef GCC_USEDEMANGLE #include <cstdlib> #include <cxxabi.h> #endif #ifdef GCC_USEDEMANGLE char const * mangledName = typeid(*this).name(); int status; char* unmangled = abi::__cxa_demangle(mangledName, 0, 0, &status); if(status == 0) { // unmangled contient le nom non décoré, ne pas oublier de libérer la mémoire free(unmangled); } else { // il y a eu un problème, on doit utiliser mangledName } #else // pas sous GCC, on utilise directement typeid(*this).name() #endif
Partager