Comprend pas le RTTI dans mon exemple

Comprend pas le RTTI dans mon exemple - C++ - Programmation

Marsh Posté le 06-04-2003 à 17:48:01    

Voici un petit bout de code. C'est un petit exemple pour jouer avec les RTTI :

Code :
  1. #include <typeinfo>
  2. #include<iostream>
  3. using namespace std;
  4. class Animal {
  5. public:
  6.   virtual void hello () {
  7.     cout<<"je suis un animal"<<endl;
  8.   }
  9. };
  10. class Chien : public Animal {
  11. public:
  12.   virtual void hello () {
  13.     cout<<"je suis un chien"<<endl;
  14.   }
  15. };
  16. class Pierre {
  17. public:
  18.   virtual void hello () {
  19.     cout<<"je suis une pierre"<<endl;
  20.   }
  21. };
  22. int main (int argc, char **argv) {
  23.   Animal *paf = new Chien ();
  24.   Pierre *caillou = new Pierre ();
  25.   paf->hello ();
  26.   caillou->hello ();
  27.   if (typeid (paf) == typeid(Chien*)) {
  28.     cout<<"paf est un chien"<<endl;
  29.   }
  30.   if (typeid (paf) == typeid(Pierre*)) {
  31.     cout<<"paf est une pierre"<<endl;
  32.   }
  33.   if (typeid (paf) == typeid(Animal*)) {
  34.     cout<<"paf est un animal"<<endl;
  35.   }
  36. }


 
Et voici la trace d'exécution obtenue :  
 
 


kadreg@rincevent:~/cplusplus/rtti$ ./rtti
je suis un chien
je suis une pierre
paf est un animal
kadreg@rincevent:~/cplusplus/rtti$

 
 
Je ne comprend pas la 3eme ligne "paf est un animal". La classe est bien instanciée en tant que Chien, Animal dispose bien d'au moins une fonction virtuelle. Je ne vois pas pourquoi j'obtient ici "paf est un animal" et pas "paf est un chien".


---------------
brisez les rêves des gens, il en restera toujours quelque chose...  -- laissez moi troller sur discu !
Reply

Marsh Posté le 06-04-2003 à 17:48:01   

Reply

Marsh Posté le 06-04-2003 à 17:54:07    

kadreg a écrit :

Voici un petit bout de code. C'est un petit exemple pour jouer avec les RTTI :

Code :
  1. #include <typeinfo>
  2. #include<iostream>
  3. using namespace std;
  4. class Animal {
  5. public:
  6.   virtual void hello () {
  7.     cout<<"je suis un animal"<<endl;
  8.   }
  9. };
  10. class Chien : public Animal {
  11. public:
  12.   virtual void hello () {
  13.     cout<<"je suis un chien"<<endl;
  14.   }
  15. };
  16. class Pierre {
  17. public:
  18.   virtual void hello () {
  19.     cout<<"je suis une pierre"<<endl;
  20.   }
  21. };
  22. int main (int argc, char **argv) {
  23.   Animal *paf = new Chien ();
  24.   Pierre *caillou = new Pierre ();
  25.   paf->hello ();
  26.   caillou->hello ();
  27.   if (typeid (paf) == typeid(Chien*)) {
  28.     cout<<"paf est un chien"<<endl;
  29.   }
  30.   if (typeid (paf) == typeid(Pierre*)) {
  31.     cout<<"paf est une pierre"<<endl;
  32.   }
  33.   if (typeid (paf) == typeid(Animal*)) {
  34.     cout<<"paf est un animal"<<endl;
  35.   }
  36. }


 
Et voici la trace d'exécution obtenue :  
 
 


kadreg@rincevent:~/cplusplus/rtti$ ./rtti
je suis un chien
je suis une pierre
paf est un animal
kadreg@rincevent:~/cplusplus/rtti$

 
 
Je ne comprend pas la 3eme ligne "paf est un animal". La classe est bien instanciée en tant que Chien, Animal dispose bien d'au moins une fonction virtuelle. Je ne vois pas pourquoi j'obtient ici "paf est un animal" et pas "paf est un chien".


 
Tout a fait normal
 
Animal *paf = new Chien()
 
 Tu definis *paf comme un animal auquel tu initialises en tant que Chien()
 
Si tu fais paf->Hello() il appelle la methode la classe chien car tu utilises virtual  
 
 Si tu recherches ce que c paf c une sorte d'Animal

Reply

Marsh Posté le 06-04-2003 à 17:56:09    

J'ai compris !
 
Je teste paf qui est un pointeur sur mon chien, et pas mon instance de chien elle même !
 
En utilisant des référence ou en demandant le typeid (*paf), ça marche tout de suite correctement.
 
 


---------------
brisez les rêves des gens, il en restera toujours quelque chose...  -- laissez moi troller sur discu !
Reply

Marsh Posté le 06-04-2003 à 17:58:57    

kadreg a écrit :

J'ai compris !
 
Je teste paf qui est un pointeur sur mon chien, et pas mon instance de chien elle même !
 
En utilisant des référence ou en demandant le typeid (*paf), ça marche tout de suite correctement.
 
 


 
c ce que j'ai dit :o

Reply

Marsh Posté le 06-04-2003 à 18:15:41    

regarde aussi du coté du dynamic_cast, typeid() a des limitations au niveau de l'héritage, on ne peut pas s'en sortir avec

Reply

Marsh Posté le 06-04-2003 à 18:17:52    

++Taz a écrit :

regarde aussi du coté du dynamic_cast, typeid() a des limitations au niveau de l'héritage, on ne peut pas s'en sortir avec


 
toutafé. Et j'aime aussi beaucoup le typeid qui marche pas sur les classes dérivant d'une classe n'ayant pas de membres virtuels.
 
Et puis typeid, c'est pas franchement conseillé comme truc ;)


---------------
brisez les rêves des gens, il en restera toujours quelque chose...  -- laissez moi troller sur discu !
Reply

Marsh Posté le 06-04-2003 à 18:19:00    

kadreg a écrit :


 
toutafé. Et j'aime aussi beaucoup le typeid qui marche pas sur les classes dérivant d'une classe n'ayant pas de membres virtuels.
 
Et puis typeid, c'est pas franchement conseillé comme truc ;)


Tiens tu m'apprends un truc là

Reply

Marsh Posté le 06-04-2003 à 18:22:08    

samuelp a écrit :


Tiens tu m'apprends un truc là


 
Voui, enlève le virtual devant le hello dans Animal. Voici la trace :  
 


kadreg@rincevent:~/cplusplus/rtti$ ./rtti
je suis un animal       /* normal, ma fonction est plus virtuelle */
je suis une pierre
paf est un animal       /* tiens, ça marche plus */
kadreg@rincevent:~/cplusplus/rtti$


 
Tu rajoute une fonction virtuelle tutu jamais appelée dans Animal, et hop, ça remarche :  
 
 


kadreg@rincevent:~/cplusplus/rtti$ ./rtti
je suis un animal
je suis une pierre
paf est un chien         /* ca remarche */
kadreg@rincevent:~/cplusplus/rtti$


Message édité par kadreg le 06-04-2003 à 18:25:07

---------------
brisez les rêves des gens, il en restera toujours quelque chose...  -- laissez moi troller sur discu !
Reply

Marsh Posté le 06-04-2003 à 20:28:51    

typeid ne sert en fait que lorsque l'on désire connaitre à tout prix le type, et ce prix, c'est la baisse de performance. Donc à utiliser avec modération, et surtout pas dans un énorme switch. voir les notions de classe abstraites, interfaces et le design pattern factory.  
 
edit ou bien

Code :
  1. class EtreVivant
  2. {
  3.   public:
  4.   virtual bool isAnimal()=0;
  5.   virtual bool isVegetal()=0;
  6. }
  7. class Animal : public EtreVivant
  8. {
  9.   public:
  10.   bool isAnimal( return true;}
  11.   bool isVegetal( return false;}
  12. }


Message édité par Taz le 06-04-2003 à 20:31:41
Reply

Marsh Posté le 06-04-2003 à 20:44:21    

++Taz a écrit :

typeid ne sert en fait que lorsque l'on désire connaitre à tout prix le type, et ce prix, c'est la baisse de performance. Donc à utiliser avec modération, et surtout pas dans un énorme switch. voir les notions de classe abstraites, interfaces et le design pattern factory.  


 
Je me demande si tu as pas le même livre que moi sous les yeux ;)


---------------
brisez les rêves des gens, il en restera toujours quelque chose...  -- laissez moi troller sur discu !
Reply

Marsh Posté le 06-04-2003 à 20:44:21   

Reply

Marsh Posté le 06-04-2003 à 20:58:57    

je lis rien en ce moment, cela dit j'ai une bonne mémoire et un cerveau.   [:tomtom75]

Reply

Marsh Posté le 06-04-2003 à 21:01:21    

comment est implanté le RTTI en C++ ? pkoi est il aussi lent ?

Reply

Marsh Posté le 06-04-2003 à 21:03:37    

chrisbk a écrit :

comment est implanté le RTTI en C++ ?  


 
Des fonctions automatiquement ajoutées dans la table des fonctions virtuelles par le compilateur (d'ou le fait que sur une classe n'ayant pas de fonctions virtuelles, ça ne marche pas), et des classes de type typeinfo crées automatiquement pour chaque classes.


---------------
brisez les rêves des gens, il en restera toujours quelque chose...  -- laissez moi troller sur discu !
Reply

Marsh Posté le 06-04-2003 à 21:05:36    

chrisbk a écrit :


pkoi est il aussi lent ?


 
Parce que c'est fait par des taches  [:daique]

Reply

Marsh Posté le 06-04-2003 à 21:06:12    

aucune idée sur l'implémentation, je voudrais pas m'avancer à dire des conneries. c lent par que c'est des informations récupérés à l'exécution (sans deconner!). le problème c que typeid nécessite une grande quantité d'information sur l'objet, et colelcter tout ça, ça prends du temps.
 
faites attention à cette petite chose: si le resultat de typeid peut etre déterminer à la compilation, le RTTI sont statiques, donc  typeid(ma_fonction()) n'exécutera pas ma_fontion

Reply

Marsh Posté le 06-04-2003 à 21:20:56    

kadreg a écrit :


 
Des fonctions automatiquement ajoutées dans la table des fonctions virtuelles par le compilateur (d'ou le fait que sur une classe n'ayant pas de fonctions virtuelles, ça ne marche pas), et des classes de type typeinfo crées automatiquement pour chaque classes.


 
 
ce c que je me suis dit au debut, mais finalement si c ca alors tu n'aurais pas eu ton pb d'animal au lieu de chien (eg avec la fonction virtuelle tu serais allé sur la "paf est un chien" ). ca n'explique pas la lenteur (genre la solution de taz devrait etre equivalente en vitesse alors), et qu'est ce qui empeche le compilo de creer une vtable pour le RTTI si il n'y en a pas ?


Message édité par chrisbk le 06-04-2003 à 21:22:22
Reply

Marsh Posté le 06-04-2003 à 22:06:12    

chrisbk a écrit :


 
 
ce c que je me suis dit au debut, mais finalement si c ca alors tu n'aurais pas eu ton pb d'animal


 
Nan, avec son code, il a comparé des pointeurs tout était statique, ils ont même pas été déréférencés (ce qui est une bonne nouvelle, ils auraient pu être nuls).

Reply

Sujets relatifs:

Leave a Replay

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