Salut,
je cherche à tester si un objet possède un attribut... afin de différencier une certaine sous-classe ;)
je ne vois pas trop comment le faire en C++ :?
Version imprimable
Salut,
je cherche à tester si un objet possède un attribut... afin de différencier une certaine sous-classe ;)
je ne vois pas trop comment le faire en C++ :?
Tester si un attribut est présent, rien de direct pour ça. Et même en moins direct, rien en restant dans la langage. Le C++ est très limité en terme d'introspection. Par contre, différentier une sous-classe peut se faire à l'aide de dynamic_cast, même si en général on préfère éviter d'avoir à différentier une sous classe.
Citation:
Envoyé par JolyLoic
je sais mais l'algo que j'utilise l'impose :cry:
j'ai essayé avec le cast... mais ça ne veut pas :?
Montre ce que tu as fait, là comme ça, j'ai du mal à deviner ce qui cloche...
Le seul moyen que je vois de tester dynamiquement si une classe possède un membre, c'est de contraindre ce membre à être hérité virtuellement. Mais le problème suggèrera peut-être une autre solution.
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14 struct AttributOwner { int attr; }; class B {...} struct X: B, virtual AttributOwner {...}; struct Y : B, virtual AttributOwner {...}; B* ptr; if (dynamic_cast<AttributOwner*>(ptr) != 0) { ... }
Une solution qui parraitrait envisageable ne serait-ce pas de rajouter un membre à la classe (par exemple un booleen HasMember, en protected) qui aurait, par défaut la valeur false, sauf justement, pour les sous classes qui auraient ce membre:question:
Tu pourrait alors gérer ton membre sous la forme de
Code:
1
2
3
4
5
6
7
8
9
10 if(HasMember) { //traiter le membre } // peut etre un autre traitement, s'il n'y est pas else { //autre traitement }
<parenthèse>
Avec la méta prog, on peut sortir le SFINAE pour détecter la présence d'un membre dans une classe.
Mais cela suppose:
- un compilo très très récent, et non buggué de préférence (surtout quand le membre est un opérateur)
- que tu connaisses déjà le type exact de ton objet -- pas ton cas visiblement, sinon tu aurais pu utiliser directement le dynamic_cast.
</>
Te voyant parti dans des hiérarchies, il est probable que tu prennes ton problème à l'envers. Tu pourrais nous en dire plus sur la tête de tes hiérarchies ? si tu peux les altérer (pour appliquer la solution de Jean-Marc) ? Peux-tu rajouter des accesseurs virtuels partiellement définis ? Qu'est-ce qui doit être résolu au final ?
Bonjour (enfin bonsoir !),
et pourquoi pas utiliser l'opérateur "typeid" (RTTI) ?
J'espère pas avoir dit une betise ... il est tard !
@+
J'ai plus régulièrement vu dynamic_cast que typeid pour faire ce genre de choses. Comme ça, non seulement on teste, mais en plus on récupère un pointeur vers la donnée du type qui nous intéresse.
merci pour toutes ses réponses, je testerais ce soir ;)
en gros, j'ai tenté un truc du genre
mais j'ai un erreur de typage :cry:Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 class Principale { public: void VInstr getPrevInstr; }; class Fils : Principale { public: VInstr* ImmediateDominatorInstr; }; void traitement(Principale* i1, Principale* i2) { /* ... */ if (i1->ImmediateDominatorInstr) { /* ... */ } else { /* ... */ } /* */ }
le but étant de faire du SSA ;)
S'il n'y a qu'un seul type fils, qu'est-ce qui t'empeche d'utiliser dynamic_cast<Fils*>(i1)? Ma solution avec une classe de base virtuelle n'a un interet que quand la hierarchie est ouverte.
Une alternative est naturellement d'avoir un membre virtuel sur Pere.
Une autre alternative est de faire de traitement une fonction polymorphe sur plusieurs parametres et donc en C++ l'utilisation d'un double dispatch comme dans le pattern visiteur.
Code:
1
2
3
4
5
6
7
8 if(Fils* f = dynamic_cast<Fils*>(i1)) { // c'est un Fils } else if(Autre_Fils* f = dynamic_cast<Autre_Fils*>(i1)) { // c'est un Autre_Fils }
:merci: à tous :D