[C++] Héritage et Polymorphisme

Héritage et Polymorphisme [C++] - C++ - Programmation

Marsh Posté le 22-05-2002 à 22:36:44    

Pour faire simple j'ai une classe de base

Code :
  1. class CMech
  2. {
  3.      /* déclaration */
  4. }
  5. Class CmechSauteur: public CMech
  6. {
  7.      void Cour();
  8. }


 
Je crée un pointeur comme ca: CMech *Mechs;
 
Quand je fais Mechs = new CMechSauteur(); Je ne peux pas accèder à la fonction Cour() de la class dérivé CMechSauteur. C'est la première fois que je me sert vraiment des classes sous C++ et je dois dire que j'ai un peu de difficulté...
 
Mais je n'ai aucune idée comment pouvoir accèder à la fonction Cour... j'ai même essayer la technique java de transtypage pour les classes mais ca marche pas  ;)

 

[jfdsdjhfuetppo]--Message édité par antp le 22-05-2002 à 22:54:27--[/jfdsdjhfuetppo]


---------------
No fucking refound :fou:
Reply

Marsh Posté le 22-05-2002 à 22:36:44   

Reply

Marsh Posté le 22-05-2002 à 22:38:30    

faut utiliser dynamic_cast il me semble.
Ou bien tu peux faire ((CmechSauteur *)Mechs)->Cour(); en faisant un cast bien bourrin, je sais pas ce que ça change exactement :D


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 22-05-2002 à 22:44:49    

antp a écrit a écrit :

faut utiliser dynamic_cast il me semble.
Ou bien tu peux faire ((CmechSauteur *)Mechs)->Cour(); en faisant un cast bien bourrin, je sais pas ce que ça change exactement :D  




 
Si ca fonctione, ca devrais me permetre d'avoir au fonction des classes dérivé qui ne sont pas dans la class de base...
 
Mais au fait si tu ne sais pas ce que ca change commeent peut tu maider ??  :D  :lol:


---------------
No fucking refound :fou:
Reply

Marsh Posté le 22-05-2002 à 22:50:02    

Je veux dire le dynamic_cast par rapport à faire (nomdelaclasse *)
 
J'ai bien compris ce que tu voulais faire...


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 22-05-2002 à 22:51:06    

antp a écrit a écrit :

J'ai bien compris ce que tu voulais faire...  




 
Ouf, heureusement :hello:


---------------
No fucking refound :fou:
Reply

Marsh Posté le 22-05-2002 à 22:52:42    

Code :
  1. class CMech
  2. {
  3.     virtual void Cour();
  4. }

Reply

Marsh Posté le 22-05-2002 à 22:54:16    

Ouais aussi.
Ou même virtual void Cour() = 0;


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 22-05-2002 à 22:57:21    

si tu veux utiliser ce genre de trucs je trouve que c'est bien mieux de faire une méthode qui éxécute une action.
 
par ex :
 
class mech
{
  virtual void execAction(char* name);
}:
 
void mech::execAction(char* name)
{
   if (!strcmp(name, "walk" ))   walk();
   if (!strcmp(name, "stop" ))   stop();
   if (!strcmp(name, "crouch" ))   crouch();
}
 
//
// puis dans la classe dérivée :
//
 
class jumperMech : public mech
{
  virtual void execAction(char* name);
}:
 
void jumperMech::execAction(char* name)
{
   mech::execAction(name);
 
   if (!strcmp(name, "run" ))   run();
}

Reply

Marsh Posté le 22-05-2002 à 23:09:48    

youdontcare a écrit a écrit :

si tu veux utiliser ce genre de trucs je trouve que c'est bien mieux de faire une méthode qui éxécute une action.
 
par ex :
 
class mech
{
  virtual void execAction(char* name);
}:
 
void mech::execAction(char* name)
{
   if (!strcmp(name, "walk" ))   walk();
   if (!strcmp(name, "stop" ))   stop();
   if (!strcmp(name, "crouch" ))   crouch();
}
 
//
// puis dans la classe dérivée :
//
 
class jumperMech : public mech
{
  virtual void execAction(char* name);
}:
 
void jumperMech::execAction(char* name)
{
   mech::execAction(name);
 
   if (!strcmp(name, "run" ))   run();
}  




 
Très bonne idée! Mais ca rajoute du traitement a executer et d'après ce que j'ai entendu dire, strcmp est assé lent... mais tout de même c'est assé interessant!  :)


---------------
No fucking refound :fou:
Reply

Marsh Posté le 22-05-2002 à 23:13:05    

i20 a écrit a écrit :

et d'après ce que j'ai entendu dire, strcmp est assé lent...


moi paco m'avait dit que mir s'écraserait sur paris ...
 
faut bien séparer les choses :
 
* strcmp() ne sera appelé que lorsque tu veux éxécuter une nouvelle action.  
 
* il y a toujours moyen de faire plus rapide, mais ça ne sert à rien d'optimiser alors que tu n'as même pas écrit le code et surtout, pas testé en situation "réelle".

Reply

Marsh Posté le 22-05-2002 à 23:13:05   

Reply

Marsh Posté le 22-05-2002 à 23:30:33    

Je vois pas trop l'interêt.
C'est complètement contraire au design objet ces If !

Reply

Marsh Posté le 22-05-2002 à 23:34:34    

Verdoux a écrit a écrit :

Je vois pas trop l'interêt.
C'est complètement contraire au design objet ces If !


if, hashtable ou autre ...  
 
mais si tu as mieux pour éxécuter une méthode propre à une classe dérivée à partir d'un pointeur d'une classe de base, je suis preneur !

Reply

Marsh Posté le 23-05-2002 à 00:59:45    

Bah, tu fais un cast :)
 
Si tu veux appeler une methode walk définie uniquement dans la classe B dérivée de A, c'est que tu supposes que ton objet est bien du type B non ? Donc, tu fais un cast :)
 
Pour info, les cast à la C sont à bannir. Tout ce qui se fesait en C avec peut se faire avec les nouveaux cast en C++ : dynamic_cast, static_cast, const_cast et reinterpret_cast.
 
la syntaxe doit etre du genre :  
CmechSauteur * pCmechSauteur = static_cast<CmechSauteur *>(pCMesh);
 
Utilise le static_cast si tu connais à l'avance le type de l'objet pointé.
Utilise le dynamic_cast si tu ne le connais pas. Si le pointeur est NULL après l'affectation, c'est que la conversion est illégale.
 
Le const_cast sert à retirer l'attibut const ( faut vraiment avoir une bonne raison de le faire, une TRES bonne )
 
Si quelqu'un pouvait me dire à quoi sert le dernier dans des mots simples, je suis preneur :)

Reply

Marsh Posté le 23-05-2002 à 05:04:01    

youdontcare a écrit a écrit :

if, hashtable ou autre ...  
 
mais si tu as mieux pour éxécuter une méthode propre à une classe dérivée à partir d'un pointeur d'une classe de base, je suis preneur !



A partir du moment ou tu veux faire ca, ca montre que tu utilises incorrectement le modele objet.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 23-05-2002 à 05:59:45    

gilou a écrit a écrit :

A partir du moment ou tu veux faire ca, ca montre que tu utilises incorrectement le modele objet.


bof. le "modèle objet", ça veut dire tellement de choses différentes pour tellement de monde.
 
prenons un exemple de la sdk de half-life. dans ce code, chaque objet dérive d'une classe de base qui propose différents services : pour chaque niveau de classe dérivée, on définit un tableau qui contient chaque variable / méthode. et pour chaque variable / méthode, on définit la position de la variable relative à this (par ex, la première variable est à this+4), son nom, son type (int, float, array, etc.), sa description (je crois). ce qui permet alors de gérer tous les objets et de changer des variables / appeler des méthodes en ayant juste un pointeur sur la classe de base. ce système permet donc de sérialiser les objets automatiquement, de les rendre accessibles par script, tout en ayant une mini doc pour chaque variable / méthode. (il y a d'autres services, comme une sorte de rtti et un tableau global par dll qui recense des méthodes statiques qui se chargent de décrire et construire les classes).
 
pour donner un exemple concret reprenant le problème de i20, supposons qu'on utilise un éditeur de niveau et qu'on veuille rajouter des monstres. on veut rajouter "CmechSauteur" - qui rajoute une action spécifique, jump() - et le faire sauter lorsque le joueur ouvre une porte. ici, on n'a qu'à chercher dans les définitions de nos classes celles qui dérivent de CMech. une fois qu'on les a trouvées, on les affiche dans un menu, l'utilisateur choisit celle à instancier, puis quelle méthode appeler lorsque la porte est ouverte.
 
cette méthode marche, je la trouve flexible et puissante - et si tu as mieux / plus clean, je répète, je suis preneur.

Reply

Marsh Posté le 23-05-2002 à 08:51:24    

bof. le "modèle objet", ça veut dire tellement de choses différentes pour tellement de monde.
 
Non. Ca a ete tres bien mis en oeuvre dans Smalltalk par exemple.
Avoir un langage avec des hierarchies de classes, ca veut pas dire suivre un modele objet.
Pour revenir a ton histoire, dans un modele objet: Tu as un objet Cmech qui reagit a un message: ouverture de porte (eventuellement broadcaste aux monstres presents dans la piece par l'objet porte). Et tu devrais avoir une methode associee a un evenement que recoit ton objet.
De ce fait, lorsque ton objet est specialise (CmechSauteur), sa reponse peut l'etre aussi, automatiquement.
 
A+,

 

[jfdsdjhfuetppo]--Message édité par gilou le 23-05-2002 à 08:52:38--[/jfdsdjhfuetppo]


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 23-05-2002 à 09:30:15    

>> Non. Ca a ete tres bien mis en oeuvre dans Smalltalk par exemple.
 
je dis ça basé sur ce que j'en connais : en c++, en javascript, en lisp - c'est différent. le dernier article que j'ai lu sur le sujet ne me donne pas non plus de définition précise : http://mumble.net/jar/articles/oo.html .
 
>> Avoir un langage avec des hierarchies de classes, ca veut pas dire suivre un modele objet.  
 
pas dit le contraire ... même si je pense que oui :)
 
>> Pour revenir a ton histoire, dans un modele objet: Tu as un objet Cmech qui reagit a un message: ouverture de porte (eventuellement broadcaste aux monstres presents dans la piece par l'objet porte). Et tu devrais avoir une methode associee a un evenement que recoit ton objet.
De ce fait, lorsque ton objet est specialise (CmechSauteur), sa reponse peut l'etre aussi, automatiquement.
 
et si on veut qu'il prenne comme comportement jumpSuperHigh() lors de "ouverture de porte" dans une autre pièce, on fait ça comment ? je ne comprends pas la possibilité (l'interêt ?)de spécialiser la réponse.
 
mais le problème ne se situe pas à ce niveau-là mais au niveau de l'éditeur, qui ne peut manipuler que la classe de base : Cmech. tu as un projet fini, tu veux rajouter une dll qui ajoute de nouveaux objets avec de nouveaux comportements. le but de l'éditeur de niveaux est de permettre aux designers d'utiliser ces nouveaux comportements (jumpVeryVeryHigh() de CmechSauteur2 lorsque le joueur arrive à telle position sur la carte). comment fait-on ça dans un système où tous les événements doivent être connus à l'avance ? (ce que tu impliques dans ton code, ce qui implique de ne pas pouvoir en rajouter ... ?)

Reply

Marsh Posté le 23-05-2002 à 14:06:45    

Citation :

je dis ça basé sur ce que j'en connais : en c++, en javascript, en lisp


Lesquels ne forcent pas a programmer en orienté objet, contrairement a Smalltalk.
 

Citation :

comment fait-on ça dans un système où tous les événements doivent être connus à l'avance ? (ce que tu impliques dans ton code, ce qui implique de ne pas pouvoir en rajouter ... ?)


Je vois pas d'ou du deduis ca, mais bon...
 

Citation :

et si on veut qu'il prenne comme comportement jumpSuperHigh() lors de "ouverture de porte" dans une autre pièce, on fait ça comment ? je ne comprends pas la possibilité (l'interêt ?)de spécialiser la réponse.


 
Je comprends pas ta question: specialiser une reponse, c'est tout simplement redefinir une methode (virtuelle quand on est en C++) dans une classe derivée. Par contre effectivement, si tes objets reagissent differement aux ouvertures de portes selon la piece, tu as des messages differents (ou le meme message, mais avec des parametres).
 
A+,

 

[jfdsdjhfuetppo]--Message édité par gilou le 23-05-2002 à 14:11:16--[/jfdsdjhfuetppo]


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 23-05-2002 à 14:42:15    

j'ai l'impression qu'on va pas s'en sortir :lol:
 
>> Je vois pas d'ou du deduis ca, mais bon...  
 
lorsque tu parles d'objet qui réagit à un message, et qu'une méthode devrait être associée pour chaque message. j'en déduis que pour créer cette méthode, il faut connaître les messages à l'avance (ouvreporte, etc.) - à moins que le langage soit dynamique, mais le topic est sur le c++.
 
>> Je comprends pas ta question: specialiser une reponse, c'est tout simplement redefinir une methode (virtuelle quand on est en C++) dans une classe derivée. Par contre effectivement, si tes objets reagissent differement aux ouvertures de portes selon la piece, tu as des messages differents (ou le meme message, mais avec des parametres).  
 
j'ai compris ce que tu voulais dire par "spécialiser la réponse", je suis d'accord avec ce point-là. le "vrai" problème dépasse ce concept : l'éditeur ne connaît que la classe de base Cmech et doit donner à l'utilisateur la possibilité de créer un script qui puisse interagir avec des méthodes définies dans des classes dérivées.

Reply

Sujets relatifs:

Leave a Replay

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