Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

RTTI et iterateurs sur Ubuntu (GCC 4.0.x)

6 réponses
Avatar
jerome moliere
Bonjour a tous,
je ne suis pas un specialiste mais l'objet ne me fait pas peur...
j'ai un probleme avec un bout de code que j'avais prepare pour mes
etudiants:
voici la version condensee (moche) de mon programme:

#include <typeinfo>
#include <iostream>
#include <string>
#include <vector>
#include <map>
using namespace std;

class Animal{
protected:
string nom;
int poids;
public:
Animal(string pnom,int ppoids){
nom=pnom;
poids=ppoids;
cout<<"constructeur animal ok.."<<endl;
}
virtual void crier()=0;
string description(){
return nom + "Animal de race " + typeid(*this).name();
}
};

class Pingouin:public Animal{
public:
Pingouin(string pnom,int ppoids):Animal(pnom,ppoids){
cout<<"Pingouin OK..."<<endl;
}
void crier(){
cout<<"Pingouin::crier() COIN!!"<<endl;
}
};

class Tigre:public Animal{
public:
Tigre(string pnom,int ppoids):Animal(pnom,ppoids){
cout<<"Tigre creee.."<<endl;
}
void crier(){
cout<<"Tigre::crier() ROUARGH"<<endl;
}
};

int main(){
Tigre t("tigrou",250);
Pingouin tux("tux",22);
cout<<"tigre :" <<t.description()<<endl;
cout<<"pingouin:" <<tux.description()<<endl;
tux.crier();
t.crier();
Pingouin* bebert=new Pingouin("bebert",12);
Pingouin* raoul=new Pingouin("raoul",11);
cout<<"type de raoul " << typeid(raoul).name() << endl;
cout<<"type de bebert =" << typeid(bebert).name() << endl;
string bebert_type=typeid(bebert).name();
string raoul_type=typeid(raoul).name();
if(bebert_type.compare(raoul_type)==0){
cout<<"types egaux"<<endl;
}
else{
cout<<"NON pas egaux"<<endl;
}
Tigre* sheer_khan=new Tigre("sheer_khan",350);
vector<Animal*> zoo;
zoo.push_back(raoul);
zoo.push_back(bebert);
zoo.push_back(sheer_khan);
map<string,int>nb_animaux;
for(vector<Animal*>::iterator
iter=zoo.begin();iter!=zoo.end();iter++){
Animal* current=*iter;
current->crier();
string type=typeid(current).name();
int nb_type=nb_animaux.count(type);
if(nb_type==0){
cout<<"insertion du type " << type << " dans la
map"<<endl;
nb_animaux[type]=1;
}
else{
cout<< "je gere deja le type = " << type << " dans
ma map avec une occurence de "
<< nb_animaux[type]<< endl;
int nb=nb_animaux[type];
cout<<"nb occurences trouvees = " << nb << endl;
nb+=1;
nb_animaux[type]=nb;
cout << "nb passe a = " << nb_animaux[type] <<
endl;

}

}

delete bebert;
delete raoul;

}

le but du programme est de revenir sur l'interet du polymorphisme, de
montrer la conjugaison dela RTTI et
des iterateurs (collections) de la STL. Seulement le hic est qu'a
l'execution G++ me sort un resultat non prevu:
tous les animaux de la collection se trouvent etre vus comme des Animal*
et non comme des Tigre* et autres Pingouin* ce qui est genant !!!

alors j'ai peut etre fait une betise mais jene la vois pas !!
merci de votre aide

Jerome

--
Using Opera's revolutionary e-mail client: http://www.opera.com/m2/

6 réponses

Avatar
Jean-Marc Bourguet
"jerome moliere" writes:

Animal* current=*iter;
current->crier();
string type=typeid(current).name();

le but du programme est de revenir sur l'interet du polymorphisme,
de montrer la conjugaison dela RTTI et des iterateurs (collections)
de la STL. Seulement le hic est qu'a l'execution G++ me sort un
resultat non prevu: tous les animaux de la collection se trouvent
etre vus comme des Animal* et non comme des Tigre* et autres
Pingouin* ce qui est genant !!!


Le type dynamique d'un pointeur, c'est son type statique et pas
pointeur vers type dynamique de l'objet pointe.

Avec
string type=typeid(current).name();
tu auras quelque chose de plus proche de ce que tu veux.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
jerome moliere
On Thu, 24 Nov 2005 17:43:46 +0100, Jean-Marc Bourguet
wrote:

"jerome moliere" writes:

Animal* current=*iter;
current->crier();
string type=typeid(current).name();

le but du programme est de revenir sur l'interet du polymorphisme,
de montrer la conjugaison dela RTTI et des iterateurs (collections)
de la STL. Seulement le hic est qu'a l'execution G++ me sort un
resultat non prevu: tous les animaux de la collection se trouvent
etre vus comme des Animal* et non comme des Tigre* et autres
Pingouin* ce qui est genant !!!


Le type dynamique d'un pointeur, c'est son type statique et pas
pointeur vers type dynamique de l'objet pointe.

je percois plus que de la logique dans ta reponse

merci beaucoup ..
j'essaie cela mais je ne doute pas du resultat :)
Avec
string type=typeid(current).name();
tu auras quelque chose de plus proche de ce que tu veux.


encore merci

(quelle rapidite en plus )
--
Using Opera's revolutionary e-mail client: http://www.opera.com/m2/


Avatar
Eric Pruneau
"jerome moliere" a écrit dans le message de news:

Bonjour a tous,
je ne suis pas un specialiste mais l'objet ne me fait pas peur...
j'ai un probleme avec un bout de code que j'avais prepare pour mes
etudiants:
voici la version condensee (moche) de mon programme:

#include <typeinfo>
#include <iostream>
#include <string>
#include <vector>
#include <map>
using namespace std;

class Animal{
protected:
string nom;
int poids;
public:
Animal(string pnom,int ppoids){
nom=pnom;
poids=ppoids;
cout<<"constructeur animal ok.."<<endl;
}
virtual void crier()=0;
string description(){
return nom + "Animal de race " + typeid(*this).name();
}
};
class Pingouin:public Animal{
public:
Pingouin(string pnom,int ppoids):Animal(pnom,ppoids){
cout<<"Pingouin OK..."<<endl;
}
void crier(){
cout<<"Pingouin::crier() COIN!!"<<endl;
}
};

class Tigre:public Animal{
public:
Tigre(string pnom,int ppoids):Animal(pnom,ppoids){
cout<<"Tigre creee.."<<endl;
}
void crier(){
cout<<"Tigre::crier() ROUARGH"<<endl;
}
};

int main(){
Tigre t("tigrou",250);
Pingouin tux("tux",22);
cout<<"tigre :" <<t.description()<<endl;
cout<<"pingouin:" <<tux.description()<<endl;
tux.crier();
t.crier();
Pingouin* bebert=new Pingouin("bebert",12);
Pingouin* raoul=new Pingouin("raoul",11);
cout<<"type de raoul " << typeid(raoul).name() << endl;
cout<<"type de bebert =" << typeid(bebert).name() << endl;
string bebert_type=typeid(bebert).name();
string raoul_type=typeid(raoul).name();
if(bebert_type.compare(raoul_type)==0){
cout<<"types egaux"<<endl;
}
else{
cout<<"NON pas egaux"<<endl;
}
Tigre* sheer_khan=new Tigre("sheer_khan",350);
vector<Animal*> zoo;
zoo.push_back(raoul);
zoo.push_back(bebert);
zoo.push_back(sheer_khan);
map<string,int>nb_animaux;
for(vector<Animal*>::iterator
iter=zoo.begin();iter!=zoo.end();iter++){
Animal* current=*iter;
current->crier();
string type=typeid(current).name();
int nb_type=nb_animaux.count(type);
if(nb_type==0){
cout<<"insertion du type " << type << " dans la
map"<<endl;
nb_animaux[type]=1;
}
else{
cout<< "je gere deja le type = " << type << " dans
ma map avec une occurence de "
<< nb_animaux[type]<< endl;
int nb=nb_animaux[type];
cout<<"nb occurences trouvees = " << nb << endl;
nb+=1;
nb_animaux[type]=nb;
cout << "nb passe a = " << nb_animaux[type] <<
endl;

}

}

delete bebert;
delete raoul;

}

le but du programme est de revenir sur l'interet du polymorphisme, de
montrer la conjugaison dela RTTI et
des iterateurs (collections) de la STL. Seulement le hic est qu'a
l'execution G++ me sort un resultat non prevu:
tous les animaux de la collection se trouvent etre vus comme des Animal*
et non comme des Tigre* et autres Pingouin* ce qui est genant !!!

alors j'ai peut etre fait une betise mais jene la vois pas !!
merci de votre aide

Jerome


Ok corrigez moi si je me trompe, mais avec typeinfo.name on est assurer
d'obtenir une
string lisible, mais le contenu n'est pas défini. Donc le standard NE
GARANTIE PAS que ce sera
le nom de la classe qui sera retourné, bien que en pratique, à peu près tous
les compilateur retournent
l'information à laquelle on s'attend...

Bon je crois bien avoir lu ceci dans Modern C++ Desing ou C++ template...
Mais je n'ai ni le standard ni ces livres
avec moi en ce moment donc je fait peut-etre erreur...

Avatar
kanze
Eric Pruneau wrote:

Ok corrigez moi si je me trompe, mais avec typeinfo.name on
est assurer d'obtenir une string lisible, mais le contenu
n'est pas défini.


On n'est même pas garanti que la chaîne soit lisible. Seulement
qu'elle se termine par un ''. Techniquement, une
implémentation qui renvoie systèmatiquemen "" est conforme.

Il y a eu une proposition de définir la valeur de la chaîne.
Elle n'a pas été adoptée. Je ne sais pas pourquoi, la fonction
est à peu près inutilisable à l'état actuel, à part des messages
de mise à point avec des compilateurs qui ont fait quelque chose
de sensible (qui ressemble en général la proposition).

Donc le standard NE GARANTIE PAS que ce sera le nom de la
classe qui sera retourné, bien que en pratique, à peu près
tous les compilateur retournent l'information à laquelle on
s'attend...


Il y a des exceptions. G++ renvoie quelque chose d'interne, on y
trouve le nom de la classe, mais avec beaucoup d'autres
caractères pour l'obfusquer.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Avatar
Yoxoman

Avec
string type=typeid(current).name();
tu auras quelque chose de plus proche de ce que tu veux.


string type = typeid(*current).name();

plutôt, je pense.

--
"A table !"
Martine Heidegger

Avatar
Jean-Marc Bourguet
Yoxoman writes:


Avec
string type=typeid(current).name();
tu auras quelque chose de plus proche de ce que tu veux.


string type = typeid(*current).name();

plutôt, je pense.


Exact. Je n'ai fait la que recopier ce qu'il avait ecrit.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org