[c++] comment recuperer le type dynamique d'un objet?

comment recuperer le type dynamique d'un objet? [c++] - Programmation

Marsh Posté le 21-08-2001 à 17:30:24    

je m'explique : j'ai une classe A et un classe B qui herite de A.
Puis j'ai un vector de A* qui peut contenir des references vers des objet de type A ou B. Y a-t-il un moyen simple de reconnaitre les A des B snas modifier les classes A et B?

Reply

Marsh Posté le 21-08-2001 à 17:30:24   

Reply

Marsh Posté le 21-08-2001 à 17:35:42    

Moi je dirais non et heureusement!!
 
Je m´explique sinon il n´y a plus vraiment d´abstraction.. Si tu stocke les adresses ss la forme de A* c bien que tu souhaites ne pas faire la distinction entre B, C ou tt les autres!! ;)


---------------
Athlon64 s754 10*200MHz - R9800Pro - 512MB DDR200MHz - ZX6RR - Q2[SupOp] - Tutorial Video: multilangues, multisstitres
Reply

Marsh Posté le 21-08-2001 à 17:47:39    

Bien sûr que oui et heureusement :) !! C'est notamment très utile si tu utilises pour le polymorphisme (les template). Il faut utiliser le dynamic_cast. La syntaxe est de la forme :
 
y = dynamic_cast<A>(x)
 
et ça te retourne NULL si ce n'est pas OK. Attention, si tu es sous VC++ il faut que dans les settings du projet sous l'onglet C/C++ dans la categorie C++ Language, tu coches l'option RTTI (Run-Time Type Information) justement.

Reply

Marsh Posté le 21-08-2001 à 17:50:37    

Drums : 1 - Hadder : 0 :)

Reply

Marsh Posté le 21-08-2001 à 18:03:29    

Gonzoide a écrit a écrit :

Drums : 1 - Hadder : 0 :)  




 
 :lol:  :lol:  :lol:  :lol:  :lol:  :lol:

Reply

Marsh Posté le 21-08-2001 à 18:05:25    

:cry:  
 
Je suis pas d´accord avec cette option!! ;)
 
(en fait je trouve pas ça très joli de recaster le A* en B*, l´utlisateur qui passe l´adress d´un A il a pas envie que l´on appelle des fonctions de B à son insu!!)
 
Cette option ne devrait pas exister.. ;)

Reply

Marsh Posté le 21-08-2001 à 18:16:01    

Pas d'accord. Effectivement cela peut être utilisé pour relacher les contraintes de types sur les paramètres et ce n'est pas bon.  
 
Mais ça n'a rien à voir avec un cast pur et dur : au contrainte grace au dynamic_cast tu check au runtime que le cast est possible.
 
Par contre cela peut être très utile voire incontournable lors de l'utilisation de templates.

 

[edtdd]--Message édité par Drums--[/edtdd]

Reply

Marsh Posté le 21-08-2001 à 18:27:44    

Java a résolu le problème : t'es OBLIGE de caster ;)

Reply

Marsh Posté le 21-08-2001 à 18:35:14    

H4dd3R a écrit a écrit :

:cry:  
 
Je suis pas d´accord avec cette option!! ;)
 
(en fait je trouve pas ça très joli de recaster le A* en B*, l´utlisateur qui passe l´adress d´un A il a pas envie que l´on appelle des fonctions de B à son insu!!)
 
Cette option ne devrait pas exister.. ;)  




 
Je suis d'accord avec toi. Si, à un moment donné, on est obligé d'utiliser les RTTI, c'est qu'il y a une grosse erreur de conception à la base.  
 
Le concept de généralisation a justement été inventé pour ne pas avoir à se poser de question sur le type de l'objet. Si le comportement du programme est influencé par le type de l'objet, c'est que les classes sont mal définies.
 
Les seules cas où le RTTI est justifié, c'est quand il y a un interfacage avec du C ou une API à base de C.


---------------
Pipiru piru piru pipiru pi
Reply

Marsh Posté le 21-08-2001 à 18:58:49    

C'est une vision trop simpliste des choses à mon avis.  
 
Encore une fois si tu utilises des templates en programmation générique tu peux facilement être confronté au pb. De plus cela permet certaines optimisations.
 
Un post qui résume bien le propos :
http://www.dcs.gla.ac.uk/mail-www/ [...] 02327.html

Reply

Marsh Posté le 21-08-2001 à 18:58:49   

Reply

Marsh Posté le 21-08-2001 à 20:24:55    

Je crois aussi que tu pourais ten sortir de la manière suivante:
 
enum ClassTypes
{ClassA,ClassB};
 
class A
{
Public:
    ClassType MyType;
     
    A(ClassType MyNewType){MyType=MyNewType}
};
 
Non?
 
[edit] J'avais pas vue qui fallait pas modifir les classes :o [/edit]

 

[edtdd]--Message édité par Ventilo--[/edtdd]

Reply

Marsh Posté le 22-08-2001 à 09:16:35    

Ne soyons pas puristes, ces choses peuvent etre utiles...
 
pour ma part, je prefere inclure des fct virtual B* A::GetB()  
{ return NULL } ou B herite de A et surcharge la methode pour renvoyer this. C'est la meme chose que le dynamic_cast sauf que ca montre que ca a ete prevu...

Reply

Marsh Posté le 22-08-2001 à 11:21:04    

BENB a écrit a écrit :

Ne soyons pas puristes, ces choses peuvent etre utiles...
 
pour ma part, je prefere inclure des fct virtual B* A::GetB()  
{ return NULL } ou B herite de A et surcharge la methode pour renvoyer this. C'est la meme chose que le dynamic_cast sauf que ca montre que ca a ete prevu...  




 
Je ne suis pas puriste, je dis simplement qu'avec une etude correcte du problème en UML, AVANT de commencer à coder permet d'éviter de genre de "raccord".
 
Pour les templates, si on est obligé de coder un comportement différent pour chaque classe, c'est qu'il faut coder ce comportement DANS la classe, c'est aussi "simple" que ça.

 

[edtdd]--Message édité par n0mad--[/edtdd]


---------------
Pipiru piru piru pipiru pi
Reply

Marsh Posté le 22-08-2001 à 11:27:26    

n0mad et moi on se comprend!! :)
 
J´essaie d´être un puriste et pour m´aider effectivement vive l´UML!! :)
 
(ceci dit les puristes peuvent parfois avoir l´air bête à se casser la tête pour rien n´est-ce pas Drums?? ;) )

Reply

Marsh Posté le 22-08-2001 à 11:38:33    

n0mad & H4dd3R > Je ne suis pas en train de dire que vous avez tord... mais quand on modifie un appli qui tourne depuis plusieurs annees, on peut etre ammenes a faire ce genres de choses parce que on ne peut pas toujours redesigner tout ce a quoi on touche... ;)
 
Sinon je suis d'accord avec vous...
Vive UML aussi...

Reply

Marsh Posté le 22-08-2001 à 11:48:20    

Euh sinon il suffit de définir une variable static const qui définit le type des classes en question...
 
pour A on lui donne la valeur 0
pour B on lui donne la valeur 1
 
et ainsi de suite... ca rejoint un peu la fonction de BENB mais je trouve que c'est un peu plus clair. Et dans tous les cas ca revient a faire du RTTI a la main, ce qui permet de mieux maitriser ce qui se passe... :??:

Reply

Marsh Posté le 22-08-2001 à 11:49:59    

n0mad a écrit a écrit :

Je ne suis pas puriste, je dis simplement qu'avec une etude correcte du problème en UML, AVANT de commencer à coder permet d'éviter de genre de "raccord".



 
C'est un peu extreme : UML n'est pas la solution a tous les problemes d'implementation, car si on l'utilise pour modeliser une appli Java, on se retrouve obligatoirement avec des casts a tous les coins de rue (ce qui tendrait a montrer qu'un outil de modelisation ne peut pas faire totalement abstarction du langage utilise lors de l'implementation)

Reply

Marsh Posté le 22-08-2001 à 12:05:20    

Gonzoide a écrit a écrit :

 
 
C'est un peu extreme : UML n'est pas la solution a tous les problemes d'implementation, car si on l'utilise pour modeliser une appli Java, on se retrouve obligatoirement avec des casts a tous les coins de rue (ce qui tendrait a montrer qu'un outil de modelisation ne peut pas faire totalement abstarction du langage utilise lors de l'implementation)  




 
C'est le cas pour Java avec son modele d'heritage limité mais c'est très rarement le cas avec C++.


---------------
Pipiru piru piru pipiru pi
Reply

Marsh Posté le 22-08-2001 à 12:20:58    

C'est exactement ce que je voulais dire :)

Reply

Marsh Posté le 22-08-2001 à 14:08:53    

tgrx a écrit a écrit :

Euh sinon il suffit de définir une variable static const qui définit le type des classes en question...
 
pour A on lui donne la valeur 0
pour B on lui donne la valeur 1
 
et ainsi de suite... ca rejoint un peu la fonction de BENB mais je trouve que c'est un peu plus clair. Et dans tous les cas ca revient a faire du RTTI a la main, ce qui permet de mieux maitriser ce qui se passe... :??:  




Chacun ces choix, le tiens est plus simple...
mais je prefere une methode virtuelle (ou un accesseur)
Le miens ne marche que si tu veux savoir si la classes est reelement celle que tu souhaite et fait le "cast" au passage...

Reply

Marsh Posté le 23-08-2001 à 01:47:40    

Ohhhhh la la la la la la
mais qu'est ce que je lis dans toutes ces réponses !!!
 
Bon il y a du bon et du pas bon dans tout ce que vous dite , il est 1h45 du mat et je ne vais pas me lancer dans un discours.
 
1 ) une classe template correctement implémentée n'a pas à connaître le type de l'objet qui lui est passé en parametre. Si ce n'est pas le cas, revoit tes algorithmes.
 
2) si tu veux connaitre dynamiquement, donc pendant l'execution, le type d'un objet, tu dois utiliser les fonctions ANSI suivantes (RTTI = run time type information):
 
type_info,  typeid
 
example :
#include <typeinfo.h>
CMaClass maclass;
if (typeid(&maclass)==typeid(CMaClass))
{
cout << " l'objet maclass est bien du type CMaClass" << endl;
}
 
renseigne toi ensuite sur les autres possibilités de type_info et typeid.
cependant ces mecanismes sont à utiliser que dans des cas particuliers. ils vont à l'encontre de la logique de la programation objet. si tu t'en sers c'est que tu ne "penses" pas en objet, encore une fois, revois tes algos.

Reply

Marsh Posté le 23-08-2001 à 06:48:42    

autre solution : comparer les pointeurs des vtables. par ex sous vc++ la vtable est stockée comme premier membre de la classe :  
*((DWORD*)this+0).
 
valaaa :D

 

[edtdd]--Message édité par youdontcare--[/edtdd]

Reply

Marsh Posté le 23-08-2001 à 10:48:46    

youdontcare a écrit a écrit :

autre solution : comparer les pointeurs des vtables. par ex sous vc++ la vtable est stockée comme premier membre de la classe :  
*((DWORD*)this+0).
 
valaaa :D  
 
 




Ca part contre c'est vraiment pas objet ! :D

Reply

Marsh Posté le 23-08-2001 à 11:18:21    

youdontcare a écrit a écrit :

autre solution : comparer les pointeurs des vtables. par ex sous vc++ la vtable est stockée comme premier membre de la classe :  
*((DWORD*)this+0).




 
GROUUIIIIIIIIIK !!! :lol:

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed