dynamic_cast, segmentation fault, constructeur par copie

dynamic_cast, segmentation fault, constructeur par copie - C++ - Programmation

Marsh Posté le 02-04-2005 à 19:52:05    

Bonjour à tous !
Voilà je découvre le c++, et je cherche à modéliser quelque chose de simple du point de vue de la conception objet, mais c'est déjà assez subtil quand on débute (et qu'on a des "habitudes" liées au langage java)
 
En gros ce que je veux faire :
 
 

Code :
  1. int main(void) {
  2.     MachineAEtat machine;
  3.     Action changementdEtat;
  4.     machine.run(changementdEtat);
  5.     return 0;
  6. }
  7. class MachineAEtat {
  8.     public:
  9.         Etat* etatCourant;
  10.         MachineAEtat() {
  11.             etatCourant = new Depart();
  12.         }     
  13.         void run(const Action& action) {
  14.             *etatCourant = etatCourant->agir(action);
  15.         }     
  16. };
  17. class Etat {
  18.     public:
  19.         virtual void agir(const Action& ) = 0;
  20. };
  21. class Depart : public Etat {
  22.     public:
  23.         Etat& agir(const Action& action) {
  24.             if (action.getMessage() == "changer" ) {
  25.                 return *(new Arrivee());
  26.             }     
  27.             return *this;
  28.         }     
  29. };
  30. class Arrivee : public Etat {
  31.     public:
  32.         Etat& agir(const Action& action) {
  33.             if (action.getMessage() == "changer" ) {
  34.                 return *(new Depart());
  35.             }     
  36.             return *this;
  37.         }     
  38. };


 
 
 
Ce à quoi j'aspire :
 
- si je suis dans Depart, que je crée un Arrivee, je veux transmettre des informations, donc je passe par un constructeur par copie.
Etat peut faire : Etat(const Etat& )
Arrivee peut faire : Arrivee(const Etat& )
Et donc moi je renvoie un *(new Arrivee(*this)) depuis la classe Départ
 
 
 
 
En gros vous en pensez quoi niveau "intégrité des objets ?" Je me demande si je ne suis pas en train de caster comme un grouik dans tous les sens :/
 
 
 
Autre question ! J'ai trouvé ceci sur un post de fin2004 du forum, au sujet du cast du C qui est à proscrire :
 

Code :
  1. class Truc {
  2.     public:
  3.         virtual void prout() {
  4.             std::cout<<"prout\n";
  5.         }
  6. }; 
  7. class Machin {
  8.     public:
  9.         virtual void roger() {
  10.             std::cout<<"roger\n";
  11.         }
  12. }; 
  13.        
  14. class Bidule : public Truc, Machin {
  15.        
  16. };         
  17.        
  18. int main() {
  19.     Bidule * bidule = new Bidule(); // on fait un bidule
  20.     Truc   * tr = (Truc*) (bidule); // bidule etant aussi un Truc,
  21.                                     //on peut le caster, n'est ce pas ?
  22.     tr->prout();
  23.     Machin * mc = (Machin* ) (tr);    // d'accord, Truc n'est pas un Machin, mais finalement,
  24.                                       // le type reel de notre "Truc"
  25.                                       // c'est "Bidule" et "Bidule" est aussi un machin. Logique, non ?
  26.        
  27.     mc->roger();  //de facon tres interessante,
  28.                   //on ne verra pas "roger" a l'ecran, mais "prout".
  29.                   //avec RTTI et dynamic cast, ca affiche bien "roger"
  30.     return 0;
  31. }


 
 
Sauf que pour moi:
avec le cast du C : ca affiche en effet ce que disent les commentaires, donc pas le résultat attendu
avec le dynamic cast : ben moi ca crash  :heink:  :??:  
 
 
 
 
Voilà, si quelqu'un veut bien éclairer ma lanterne  :jap:


---------------
Il y a autant d'atomes d'oxygène dans une molécule d'eau que d'étoiles dans le système solaire.
Reply

Marsh Posté le 02-04-2005 à 19:52:05   

Reply

Marsh Posté le 02-04-2005 à 20:31:54    

active les RTTI dans ton compilateur (de ******) ?

Reply

Marsh Posté le 02-04-2005 à 20:52:03    

Taz a écrit :

active les RTTI dans ton compilateur (de ******) ?


 
Ben je compile avec g++, a priori il ne semble pas y avoir de trucs supplémentaires à activer.
 
Par exemple sur un truc comme ça ça marche bien :

Code :
  1. #include <typeinfo>
  2. #include <iostream>
  3. using namespace std;
  4. class A {
  5.     public:
  6.         virtual void do_it() { cout << "I'm an A" << endl; }
  7. };
  8. class B : public A {
  9.     public:
  10.         void do_it() { cout << "I'm a B" << endl; }
  11. };
  12. class C : public A {
  13.     public:
  14.         void do_it() { cout << "I'm a C" << endl; }
  15. };
  16. int main(void) {
  17.     A a;
  18.     B b;
  19.     C c;
  20.     A* obj;
  21.     cout << typeid(obj).name() << endl;
  22.     obj = &a;
  23.     cout << typeid(*obj).name() << endl;
  24.     obj = &b;
  25.     cout << typeid(*obj).name() << endl;
  26.     if (typeid(*obj) == typeid(b))
  27.         cout << "on pointe un B" << endl;
  28.     obj = &c;
  29.     cout << typeid(*obj).name() << endl;
  30.     return 0;
  31. }


Message édité par Xavier_OM le 02-04-2005 à 20:52:21

---------------
Il y a autant d'atomes d'oxygène dans une molécule d'eau que d'étoiles dans le système solaire.
Reply

Marsh Posté le 02-04-2005 à 21:14:37    

je vois pas de dynamic_cast là
 
et ton utilisation de typeid() est exactement l'usage qu'il ne faut pas en faire


Message édité par Taz le 02-04-2005 à 21:15:06
Reply

Marsh Posté le 02-04-2005 à 21:17:06    

et n'oublie pas le destructeur virtuel vu que tu veux pas du polymorphisme. Dans ton cas, je vois pas l'intérêt du dynamic_cast vu que le dispatching est fait par le mécanisme de virtual.

Reply

Marsh Posté le 02-04-2005 à 21:32:02    

Code :
  1. #include <typeinfo>
  2. #include <iostream>
  3. #include <vector>
  4. using namespace std;
  5. class Graine
  6. {
  7. public:
  8.   virtual ~Graine() { }
  9. };
  10. class BonGrain : public Graine
  11. {
  12. public:
  13.   virtual ~BonGrain() { }
  14. };
  15. class Ivraie : public Graine
  16. {
  17. public:
  18.   virtual ~Ivraie() { }
  19. };
  20. void separe(vector<Graine*> &recolte, vector<BonGrain> &grains, vector<Ivraie> &ivraies)
  21. {
  22.   for(vector<Graine*>::iterator i(recolte.begin()); i != recolte.end(); ++i)
  23.     {
  24.       if(BonGrain* bon_grain = dynamic_cast<BonGrain*>(*i))
  25. {
  26.   grains.push_back(*bon_grain);
  27. }
  28.       else if(Ivraie* ivraie = dynamic_cast<Ivraie*>(*i))
  29. {
  30.   ivraies.push_back(*ivraie);
  31. }
  32.       else
  33. {
  34.   cerr << "Je ne sais pas ce que c'est que cette cochonnerie !\n";
  35. }
  36.       delete *i;
  37.     }
  38.   recolte.clear();
  39. }
  40. int main()
  41. {
  42.   vector<Graine*> recolte;
  43.   vector<BonGrain> grains;
  44.   vector<Ivraie> ivraies;
  45.   recolte.push_back(new BonGrain);
  46.   recolte.push_back(new Ivraie);
  47.   recolte.push_back(new BonGrain);
  48.   separe(recolte, grains, ivraies);
  49.   cout << grains.size() << " bon grains et " << ivraies.size() << " ivraies\n";
  50.   return 0;
  51. }

un exemple complet de dynamic_cast.

Reply

Marsh Posté le 02-04-2005 à 22:01:42    

Merci pour l'exemple  :jap:  
 
(Pour le dynamic_cast c'est plus pour comprendre pourquoi le truc trouvé sur ce forum crash chez moi que pour mes états :D)


---------------
Il y a autant d'atomes d'oxygène dans une molécule d'eau que d'étoiles dans le système solaire.
Reply

Marsh Posté le 02-04-2005 à 22:15:10    

ton trucs avec tes états à l'air crade comme pas possible. compile en -Wall -std=c++98 -Weffc++ déjà, et ensuite, va falloir apprendre à gérer la mémoire, parce que là ça fuit et ça corromp à tout va

Reply

Marsh Posté le 02-04-2005 à 22:42:57    

Taz a écrit :

ton trucs avec tes états à l'air crade comme pas possible. compile en -Wall -std=c++98 -Weffc++ déjà, et ensuite, va falloir apprendre à gérer la mémoire, parce que là ça fuit et ça corromp à tout va


 
Sympa cette option -Weffc++  :ouch:  :jap:  
En effet je ne maitrise pas trop les destructeurs et les fuites mémoires.
 
Bon 0 erreurs 0 warnings pour "g++ -Wall -Wshadow -W -std=c++98"
4 pages de warnings avec -Weffc++  :cry:  
 
 
Bon ben j'y retourne
 


---------------
Il y a autant d'atomes d'oxygène dans une molécule d'eau que d'étoiles dans le système solaire.
Reply

Sujets relatifs:

Leave a Replay

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