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 et polymorphisme info ?


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Août 2009
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2009
    Messages : 42
    Par défaut héritage et polymorphisme info ?
    salut a tous j'ai besoin de ca :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    class base
    {
    public:
    void funcCommune(void);
    int paramCommun;
    }
     
    class enfantA : base
    {
      enfantA(){}
      ~enfantA(){}
    }
     
    class enfantB : base
    {
      enfantB(){}
      ~enfantB(){}
    }
     
    class enfantC : base
    {
      enfantC(){}
      ~enfantC(){}
    }
    voila pour la déclaration et j'aurais besoin d'avoir une fonction qui a une classe return "base"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    :
    class autreOBJ
    {
    .
    .
    .
     base funtion_retour_base()
     {
      enfantA objectA;
      return (base) objectA;
     }
    .
    .
    .
    }
    voila ... je ne sais pas si j'ai été clair :s mais c'est ce dont j'ai besoin .

    voici donc ma question : Est ce que je procède de la bonne façon ou y a-t-il un autre/meilleur moyen de faire ce que je veux ?

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Tout d'abord, tu n'a spas besoin de définir le constructeur/destructeur pour les classes que tu présentes. C++ le fait pour toi.

    Ensuite, sur ta fonction, tu n'as pas besoin de transtyper objectA en base, puisque objectA est intrinsèquement un objet de type base, car il en dérive.

    En outre, si le transtypage avait été nécessaire, il eût été préférable d'utiliser static_cast<base>(objectA), plutôt que ce transtypage à la C.

  3. #3
    Membre Expert
    Homme Profil pro
    Inscrit en
    Décembre 2010
    Messages
    734
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 734
    Par défaut
    Petite question, est-ce que ce n'est pas un cas où on risque un slicing? Il faudrait que ce soit un (smart) pointer, non?
    @kev: je crois qu'en renvoyant un objet comme tu le fais tu risque un problème car il sera fait une recopie dans un nouvel objet de type base qui ne tiendra pas compte du type effectif de l'objet d'origine renvoyé, avec perte des données spécifiques du type enfantA, et de l'information du type effectif enfantA

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Citation Envoyé par therwald Voir le message
    Petite question, est-ce que ce n'est pas un cas où on risque un slicing? Il faudrait que ce soit un (smart) pointer, non ?
    Si , mais ce n'est pas forcément gênant. S'il n'a besoin que des fonctionnalités du type base...

    Citation Envoyé par therwald Voir le message
    @kev: je crois qu'en renvoyant un objet comme tu le fais tu risque un problème car il sera fait une recopie dans un nouvel objet de type base qui ne tiendra pas compte du type effectif de l'objet d'origine renvoyé, avec perte des données spécifiques du type enfantA, et de l'information du type effectif enfantA
    Oui, mais comme manifestement, il veut un objet de type base, et se contrefiche de ce que rajoutent ses classes dérivées, il n'y a pas de problème.

  5. #5
    Membre Expert
    Homme Profil pro
    Inscrit en
    Décembre 2010
    Messages
    734
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 734
    Par défaut
    C'est ce dont je voudrais m'assurer...peut-être n'a-t-il pas conscience du problème...pour quoi sous-typer si tu n'utilises pas la polymorphie?
    Il s'attend peut-être à voir jouer ses redéfinitions, ce qui ne sera pas le cas avec ce code.
    Mais il n'y a que lui qui a la réponse à cette question.

  6. #6
    Membre Expert
    Homme Profil pro
    Inscrit en
    Décembre 2010
    Messages
    734
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 734
    Par défaut
    Je suis tombé sur ceci
    je vais créer un post concernant l'héritage et le polymorphisme avec une version théorique
    au détour de ça:
    http://www.developpez.net/forums/d11...iation-classe/
    La méthode serait donc une factory method, et là on ne veut surtout pas perdre le type originel, à mon avis.
    Donc non, pour moi ce n'est pas bon, il faut renvoyer un smart-pointer sur le type de base et non une copie dans le type de base. Et utiliser une allocation dynamique dans la factory_method...et résoudre le problème de la durée de vie de l'instance.

  7. #7
    Membre Expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Par défaut
    Citation Envoyé par therwald Voir le message
    Petite question, est-ce que ce n'est pas un cas où on risque un slicing? Il faudrait que ce soit un (smart) pointer, non?
    @kev: je crois qu'en renvoyant un objet comme tu le fais tu risque un problème car il sera fait une recopie dans un nouvel objet de type base qui ne tiendra pas compte du type effectif de l'objet d'origine renvoyé, avec perte des données spécifiques du type enfantA, et de l'information du type effectif enfantA
    C'est tout à fait exact : tu tentes de mélanger polymorphisme et sémantique de valeur, ce qui ne cohabite pas bien ensemble !

    Cela ne fonctionne pas, car tu tentes d'effectuer une copie depuis enfantA vers un objet base qui ne peut rien contenir de plus qu'un objet base. L'objet sera tronqué et tu risques de te retrouver face à des comportements ingérables. Ce code par exemple, qui compile pourtant sans erreur, le montre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    #include <iostream>
     
    class base
    {
      int paramCommun;
     
    public:
      base() : paramCommun(5)
      {}
     
      virtual int funcCommune(void)
      {
        return paramCommun;
      }
    };
     
    class enfantA : public base
    {
      int paramPasCommun;
     
    public:
      enfantA() : base(), paramPasCommun(10)
      {}
     
      virtual int funcCommune(void)
      {
        return paramPasCommun;
      }
    };
     
    struct autreOBJ
    {
     base funtion_retour_base()
     {
      enfantA objectA;
      return objectA; // L'objet objectA est tronqué et "paramPasCommun" est perdu !
     }
    };
     
    int main(int argc, char* argv[])
    { 
      enfantA enfantNormal;
      std::cout << enfantNormal.funcCommune() << std::endl; // Affiche 10 comme prévu
     
      autreOBJ obj;
      base enfantPasNormal = obj.funtion_retour_base();
      std::cout << enfantPasNormal.funcCommune() << std::endl; // Affiche 5, ce qui n'est pas correct !
    }
    Le polymorphisme est inutilisable et dangereux ! Soit tu n'as pas besoin de paramètres propres aux classes enfant, ni de fonctions virtuelles surchargées dans les enfants, et dans ce cas, tu n'as pas besoin de faire de l'héritage et ton problème doit être résolu autrement, soit tu as besoin du polymorphisme, et voici un code adapté :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    #include <iostream>
     
    class base
    {
      int paramCommun;
     
    public:
      base() : paramCommun(5)
      {}
     
      virtual int funcCommune(void)
      {
        return paramCommun;
      }
    };
     
    class enfantA : public base
    {
      int paramPasCommun;
     
    public:
      enfantA() : base(), paramPasCommun(10)
      {}
     
      virtual int funcCommune(void)
      {
        return paramPasCommun;
      }
    };
     
    struct autreOBJ
    {
     base * funtion_retour_base()
     {
      enfantA * pObjectA = new enfantA();
      return pObjectA; // L'objet objectA est tronqué et "paramPasCommun" est perdu !
     }
    };
     
    int main(int argc, char* argv[])
    { 
      enfantA enfantNormal;
      std::cout << enfantNormal.funcCommune() << std::endl; // Affiche 10 comme prévu
     
      autreOBJ obj;
      base * pAutreEnfant = obj.funtion_retour_base();
      if(pAutreEnfant)
      {
        std::cout << pAutreEnfant -> funcCommune() << std::endl; // Affiche 10, ce qui est correct
        delete pAutreEnfant; // On libère la mémoire
        pAutreEnfant = 0;
      }
    }
    Si tu utilises le polymorphisme, gare à la gestion de la mémoire. La durée de vie de l'instance, comme dit thewald.

    PS : Tu as oublié de déclarer publiquement l'héritage, ce qui a du te poser problème et te pousser à venir poster ici, car l'héritage est privé par défaut et le code ne compile alors pas.

  8. #8
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Citation Envoyé par jblecanard Voir le message
    Soit tu n'as pas besoin de paramètres propres aux classes enfant, ni de fonctions virtuelles surchargées dans les enfants, et dans ce cas, [B] tu n'as pas besoin de faire de l'héritage
    Si tu ne te bases que sur le message de ce fil, je ne suis pas d'accord.
    Une autre fonction pourrait avoir ces besoin, mais pas celle-ci.

  9. #9
    Membre Expert
    Homme Profil pro
    Inscrit en
    Décembre 2010
    Messages
    734
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 734
    Par défaut
    Citation Envoyé par oodini Voir le message
    Si tu ne te bases que sur le message de ce fil, je ne suis pas d'accord.
    Une autre fonction pourrait avoir ces besoin, mais pas celle-ci.
    Le code est visiblement très réduit et démuni de sens. Si on veut une instance de base, et que la classe base a du sens en elle-même, POURQUOI aller instancier un objet de type enfantA?

Discussions similaires

  1. héritage et polymorphisme
    Par julien.metais dans le forum Hibernate
    Réponses: 3
    Dernier message: 17/05/2009, 09h58
  2. Réponses: 10
    Dernier message: 17/07/2008, 20h01
  3. héritage et polymorphisme
    Par davdou dans le forum JSF
    Réponses: 2
    Dernier message: 23/11/2007, 09h51
  4. [C#] Information sur héritage et polymorphisme
    Par LE NEINDRE dans le forum C#
    Réponses: 21
    Dernier message: 14/06/2007, 11h00
  5. Réponses: 19
    Dernier message: 05/06/2007, 08h13

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