IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Héritage : quelle est la fille ?


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert Avatar de fregolo52
    Homme Profil pro
    Développeur C
    Inscrit en
    Août 2004
    Messages
    2 366
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Août 2004
    Messages : 2 366
    Par défaut Héritage : quelle est la fille ?
    Bonjour,

    J'ai l'impression de poser une question bateau, mais je dois chercher comme un pied vu que je ne trouve pas grand chose.

    Je voudrais m'assurer que j'utilise la bonne méthode.

    J'ai une classe de test (Test) qui a comme membre la classe mère (Mere), dans une méthode, j'ai :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void Test::Init(int i)
    {
      if (i == 1)
        mere = new Fille1;
      else
        mere = new Fille2;
    }
    Plus loin j'ai besoin d'une méthode de Fille1 qui n'existe pas dans Fille2.
    Pour m'assurer que c'est la bonne classe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Fille1* fille =  dynamic_cast<Fille1*>(mere);
    Donc, si c'est Fille2, fille sera nulle.

    C'est bien ça ? Y a-t-il une autre méthode (plus sûre) ?

    Merci.

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 153
    Billets dans le blog
    4
    Par défaut
    Bonjour,

    l'héritage c'est une relation class Fille : public (protected/private) Mere.
    Dans ton cas tu as composé Mere dans Test.

    Pour ton 2° cas et la méthode, plusieurs possibilités
    - celle que tu décris
    - une interface commune dans la classe Mere et laisser faire le polymorphisme (virtual, ...)
    - sûrement d'autres plus ou moins farfelues
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Membre émérite

    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 533
    Par défaut
    Tu peux déclarer ta méthode en virtuelle pure dans Mere, l'implémenter dans Fille1 et laisser Fille2 avec une implémentation vide (ou déclenchant une exception). Du coup ton objet mere est polymorphe, et mere.tamethode() génère le bon comportement quoiqu'il arrive, sans devoir passer par dynamic_cast.

  4. #4
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    De manière générale, la nécessité de "downcaster" un objet en un objet du type de la classe fille met en évidence un problème de conception à la base...

    Cela peut etre du à trois causes différentes :
    1. Soit, tu as choisi de recourir à l'héritage alors qu'il n'y avait pas lieu de le faire (il faut vraiment veiller à respecter le LSP (le principe de substitution de Liskov, si tu es allergique aux abréviations ) chaque fois que tu décides de recourir à l'héritage
    2. Soit, tu es remonté "trop haut" dans ta hiérarchie (dont on considère que LSP est respecté pour tous les types envisagés) au niveau du type d'objets que tu maintiens dans ta collection
    3. Soit tu essayes de donner à un type en particulier une responsabilité qu'il ne devrait pas avoir et qui devrait, dés lors être déléguée à un nouveau type particulier
    Le premier cas est une pure décision de conception : il ne faut pas envisager l'héritage public uniquement parce que l'on se rend compte que deux classes présentent une interface commune...

    L'héritage public est la relation la plus forte qui puisse exister entre deux classes, dans le sens où (c'est ce que nous indique LSP ) un objet dont le type est une classe qui dérive d'une autre doit pouvoir passer pour être un objet de la classe de base sans que cela ne nuise au bon déroulement du programme (modulo les adaptations éventuelles de comportement).

    On dit souvent que l'héritage est une relation EST-UN, mais c'est vraiment à prendre du point de vue sémantique du terme dans le sens où, si tu ne peux décemment pas estimer qu'un objet du type dérivé EST-UN objet du type de la classe de base, c'est qu'il est sans doute préférable d'envisager une relation moins forte (comme l'agrégation, par exemple)

    Le deuxième cas dépend fortement de ta conception générale, mais, en gros, s'il faut que tu fasses le distingo entre un type dérivé particulier et un autre, peut etre devrais tu envisager la solution qui consiste à garder à jour une collection de pointeurs sur ce type particulier, de manière à te permettre de les traiter par lot

    Le troisième cas est, malheureusement, très fréquent, et part aussi d'un problème de conception, du essentiellement au fait que la responsabilité de la classe qui va utiliser les objets de type dérivés n'est pas clairement définie, ou que la "granularité" de la responsabilité de cette classe n'est pas adaptée au cas auquel tu es confronté...

    Dans ce cas, tu pourras surement t'en sortir en mettant en place le "double dispatch" qui permettra à une classe d'effectuer un traitement particulier en fonction du type réel de l'objet à traiter.

    L'exemple "générique" de mise en place du double dispatch est le patron de conception connu sous le terme de "visiteur", dont tu pourrais peut etre t'inspirer
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  5. #5
    Membre Expert Avatar de fregolo52
    Homme Profil pro
    Développeur C
    Inscrit en
    Août 2004
    Messages
    2 366
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Août 2004
    Messages : 2 366
    Par défaut
    Bonjour

    merci pour vos réponses.

    koala01, avec ta description, je me rends mieux compte (même si j'avais des soupçons) que je fais un truc dégueulasse.

    En fait, le downcast est lié au fait que je ne veux pas modifier la Mere parce qu'elle a beaucoup trop de filles. C'est un outil de config pour des dixièmes d'applis (donc autant de filles). Je ne bosse que sur une des filles. (hors contexte ça pourraît être louche )

    je vais essayer de réfléchir pour faire autrement.

  6. #6
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par fregolo52 Voir le message
    Bonjour

    merci pour vos réponses.

    koala01, avec ta description, je me rends mieux compte (même si j'avais des soupçons) que je fais un truc dégueulasse.

    En fait, le downcast est lié au fait que je ne veux pas modifier la Mere parce qu'elle a beaucoup trop de filles. C'est un outil de config pour des dixièmes d'applis (donc autant de filles). Je ne bosse que sur une des filles. (hors contexte ça pourraît être louche )

    je vais essayer de réfléchir pour faire autrement.
    Dans ce cas, je présume que chaque application a une classe fille qui lui est propre et que tu n'utiliseras jamais une classe fille utilisée par une application différente...

    La meilleure solution est donc, au sein de l'application, de travailler directement avec le type réel de ton outil de configuration

    Ceci dit, le downcast peut malgré tout etre envisagé si ( et seulement si ) tu peux respecter malgré tout ce que l'on appelle l'OCP (le principe "ouvert fermé"), qui dit qu'un code doit etre ouvert aux évolutions et fermé aux modifications.

    Dans le cas présent, le fait que, quoi qu'il arrive, tu ne devra sans doute jamais aller rajouter un type de la classe dérivé lors de ton downcast semble plaider en faveur d'une exception à la règle

    Mais cette exception doit alors être mise en place de manière cohérente, et il faut impérativement éviter que le downcast ne soit utilisé "partout dans le code"...

    L'idéal étant alors une fonction qui appellera static_cast ( après tout, on est sur du type que l'on veut récupérer ) et qui elle sera appelée dans le code
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 8
    Dernier message: 27/01/2014, 10h36
  2. Héritage multiple, quelle est la meilleure solution?
    Par thunderfear dans le forum Langage
    Réponses: 1
    Dernier message: 06/02/2010, 20h32
  3. execute/perform quelle est la différence?
    Par stago dans le forum Struts 1
    Réponses: 2
    Dernier message: 30/06/2004, 10h51
  4. Quelle est la fiabilité du protocole SSL ?
    Par Anonymous dans le forum Développement
    Réponses: 5
    Dernier message: 05/09/2002, 13h31

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo