J'ai une petite question concerant le dynamic_cast. J'ai une classe de base abstraite qui possède une fonction virtuelle pure. J'ai deux classes qui dérivent de cette classe abstraite et qui en plus de la fonction héritée ont d'autres fonctions membres.
class Abstraite{
public:
virtualvoid fonction()=0;
};
class DeriveeA: public Abstraite{
public:
virtualvoid fonction();
virtualint foo();
};
class DeriveeB: public Abstraite{
public:
virtualvoid fonction();
virtualdouble maFonction(int);
A partir de cette arborescence, j'ai réalisé une collection hétérogène de Abstraite*.
std::vector<Abstraite*> collection;
collection.push_back(new DeriveeA);
collection.push_back(new DeriveeB);
//...
Je n'ai aucun problème pour utiliser la fonction membre "fonction()", mais j'aimerais pouvoir utiliser les fonctions membres de DeriveeA et DeriveeB. Pour ce faire, il y a le dynamic_cast
Et c'est là qu'apparaît mon problème. On dit partout que le dynamic_cast c'est mal, que c'est le signe d'une mauvaise conceptionet ainsi de suite. Ma question est donc: Comment faire autrement, de manière propre ?
Merci d'avance à ceux qui ont une réponse à cette épineuse question.
La réponse passe avant tout par une étude du contexte. Car techniquement, dynamic_cast est la solution à ce problème précis (sans parler de boost::polymorphic_cast, de static_cast, etc.) ; c'est juste qu'arriver à ce problème dénote souvent d'un mauvais choix en amont.
Donc si tu veux une solution il faut nous dire ce que tu veux faire avec ce vilain down_cast.
Et puis, tu es peut-être dans l'un des rares cas où le down_casting est justifié. C'est pas non plus une tare de l'utiliser, il n'est tout de même pas là pour rien
Citation : Pas de titre
Un truc bete et simple qui marche bien :
Tant qu'à faire du RTTI autant utiliser celui fourni par le langage... Vous pensez qu'il fait quoi dynamic_cast, si ce n'est exactement ça (en mieux) ?
Et puis là c'est un problème de conception, on ne cherche pas à trouver un autre moyen de faire ce que dynamic_cast fait déjà très bien, mais d'éviter d'avoir à l'utiliser.
Pour compléter la réponse de Laurent, j'ai une question.
Quel est le sens de cette liste hétérogène? Et surtout quel est le sens d'appliquer au cas par cas un traitement sur ses éléments, traitement qui ne soit pas commun (virtuel) à tous les éléments ?
Je suis gestionnaire d'un aéroport. J'ai une classe abstraite "Véhicule" avec des sous-classes "Avion" et "Voiture". Ceci est très pratique pour gérer les tâches communes, comme faire le plein d'essence, chager une roue ou réparer qui sont des tâches communes de ces "Véhicule".
D'autre part je possède une liste de "Conducteurs" qui sont soit des "Pilotes", soit des "Chauffeurs". Egalement la liste est ici bien pratique puisqu'elle permet de gérer le salaire, les heures de travail,...
Quand arrive le soir, j'aimerais bien ranger mes "Véhicules" dans les hangars. Pour ce faire, les pilotes rangent les avions et les chauffeurs les voitures. Pour ce faire j'aimerais bien réaliser une fonction dans la classe "Conducteur" du type "void parquer(Véhicule& v)" ou "void parquer(Véhicule* ptr)". Et ensuite spécialiser cette fonction dans "Pilote" (par exemple) de manière à ce que ce-dernier puisse ranger l'avion dans le hangar en utilisant des fonctions spécifiques aux "Avions" comme par exemple "rétro-freins" ou "réglageDérive", c'est-à-dire en transtypant le "Véhicule" en "Avion" par exemple.
Je sais pas si mon exemple est plus clair comme ça.
Cela me fait penser à une discussion [1] que j'avais eu avec Jean-Marc au sujet des hiérarchies parallèles -- j'ai l'impression que mon exemplaire de son pdf a disparu avec mon disque dur. Cela remonte un peu, et je crois bien que j'étais resté sur ma faim -- avec une solution "tordue", mais sans dynamic_cast.
Dans ton cas, tu peux peut-être t'en sortir juste avec des visiteurs (design pattern) pour mettre en oeuvre le double-dispatch.
[1] Si jamais le lien est corrompu, copie-colle ce qui suit: http://groups.google.fr/group/fr.comp.lang.c++/browse_frm/thread/688c0ad6f7a4935e/f426236fc36665bd
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Recueil de code C et C++ http://fvirtman.free.fr/recueil/index.html