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 :

Appel méthode classe fille, dont classe mère virtuelle


Sujet :

C++

  1. #1
    Membre expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Points : 3 532
    Points
    3 532
    Par défaut Appel méthode classe fille, dont classe mère virtuelle
    Bonjour,

    Je fais très rarement du C++ (et je suis assez célèbre pour dire beaucoup BEAUCOUP de mal de la POO en général), mais je me suis lancé sur un projet en groupe dont le C++ l'a emporté (heureusement, certaines parties sont en pure-good-old-C).

    Bref, j'ai beaucoup oublié le fonctionnement des appels de fonctions lors d'héritage avec classes mères virtuelles.
    Et je suis perdu car je ne sais plus quel mot clé utiliser (typename ?).

    Voici les classes "simplifiées" au maximum pour mon problème (PrintNameClass contient l'écriture du nom de la classe courante, sauf pour la Class1 évidemment) :
    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
    class Classe1
    {
      public:
      virtual voit PrintNameClass(void) = 0;
    };
     
    class Classe2 : public Classe1
    {
      public:
      virtual void PrintNameClass(void);
    };
     
    class Classe3 : public Classe2
    {
      public:
      void PrintNameClass(void);
    }
    Voici mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void maFonction(Classe2 myObj)
    {
      myObj.PrintNameClass();
    }
     
    int main(void)
    {
      Classe3 myObj;
     
      myObj.PrintNameClass();
      maFonction(myObj);
    }
    Lors du runtime, je me retrouve donc avec 2 print (ce qui est normal), mais, ils m'affichent :
    Classe3
    Classe2
    Je voudrais pouvoir appeler la méthode PrintNameClass de la classe la plus "en bas" (Class3 pour le coup) plutôt que celle de la première classe l'implémentant, comment faire ?
    J'ai un lointain souvenir de "typename", mais en cherchant, cela n'intervient qu'à l'intérieur de templates, donc complètement en dehors de l'héritage.
    J'ai farfouillé les cours, mais je me retrouve soit dans les "bases-bases-bases" du C++, soit dans les parties trop avancées.

    Merci d'avance à vous !
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

  2. #2
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Bonjour,

    Pour utiliser le polymorphisme, il te faut utiliser un pointeur ou une référence.

    Là tu va copier la "partie Classe 2" de ton instance de "Classe 3", donc tu aura au final une instance de Classe 2 qui ne sera pas une Classe 3.

  3. #3
    Membre expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Points : 3 532
    Points
    3 532
    Par défaut
    Arrh... j'ai hésité à le faire ne plus ! xD
    Et je me suis dis que peut être que non...

    Bref... je l'ai mis en mode référence :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void maFonction(Classe2 &myObj)
    {
      myObj.PrintNameClass();
    }
     
    int main(void)
    {
      Classe3 myObj;
     
      myObj.PrintNameClass();
      maFonction(myObj);
    }
    Et ça fonctionne en effet.
    Et c'est logique le coup de la copie de la partie "Classe2" uniquement.

    Merci !
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

  4. #4
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 275
    Points : 10 985
    Points
    10 985
    Par défaut
    PS: un classe n'est pas virtuelle.
    En revanche, une classe de base peut être virtuelle relativement à un héritage.
    Dans
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    struct A {};
    struct B : A {};
    struct C : virtual A {};
    A est une classe de base virtuelle pour C mais pas pour B.
    Ce que tu as désigné comme classe virtuelle, est ce que l'on appelle une classe abstraite (qui a la particularité d'avoir toutes ses fonctions virtuelles pures)

    Concernant ton problème, Je t'invite à interdire l'héritage sur tes classes qui ont vocation à être dérivées (car techniquement c'est un sac de noeuds sans solution propre, car sémantiquement cela n'a jamais aucun sens que de dupliquer des entités, et que pratiquement on n'en a jamais besoin (de copier des entités))
    Ainsi, le compilateur t'aurait engueulé dès le début au lieu de te laisser faire ce que tu ne voulais pas faire.
    (le comment est dans la FAQ)
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  5. #5
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Citation Envoyé par Luc Hermitte Voir le message
    Je t'invite à interdire l'héritage sur tes classes qui ont vocation à être dérivées
    Qui n'ont pas vocation à être dérivées non?

  6. #6
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Oups.

    Presque. Il fallait lire:
    -> interdire la copie sur les classes qui ont vocation à être dérivées.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  7. #7
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Citation Envoyé par Luc Hermitte Voir le message
    Ce que tu as désigné comme classe virtuelle, est ce que l'on appelle une classe abstraite (qui a la particularité d'avoir toutes ses fonctions virtuelles pures)
    La formulation est ambigüe, je vais donc clarifier un peu:
    • Une classe abstraite est une classe qui possède une ou plusieurs fonction(s) virtuelle(s) pure(s).
    • Cette classe abstraite en particulier a toutes ses fonctions virtuelles pures, et aucune variable. Dans certains milieux, on appelle ça une interface, en raison des similarités avec les plate-formes implémentant directement ce concept (.Net, Java...)
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

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

Discussions similaires

  1. Twisted: Appel méthode dataReceived de la classe mère
    Par llusca dans le forum Général Python
    Réponses: 2
    Dernier message: 29/10/2014, 12h51
  2. Méthode classe mère appelle méthode surdéfini de la classe fille
    Par djrilhouse dans le forum Débuter avec Java
    Réponses: 2
    Dernier message: 21/03/2013, 20h24
  3. Appel de méthode protected dans une classe fille
    Par Le Mérovingien dans le forum C++
    Réponses: 11
    Dernier message: 05/06/2012, 16h04
  4. Appel de fonction depuis une classe fille
    Par lhpp dans le forum Interfaces Graphiques en Java
    Réponses: 8
    Dernier message: 26/04/2006, 22h02
  5. [debutant]appeller une fonction d'une classe fille et mere ?
    Par Battosaiii dans le forum Débuter
    Réponses: 1
    Dernier message: 12/11/2005, 12h56

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