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
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.
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...
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
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager