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 :

Question sur l'héritage


Sujet :

C++

  1. #1
    Membre confirmé
    Inscrit en
    Septembre 2004
    Messages
    187
    Détails du profil
    Informations forums :
    Inscription : Septembre 2004
    Messages : 187
    Par défaut Question sur l'héritage
    Bonjour,

    J'ai trois classes:
    C qui hérite de B qui hérite de A

    Les explications que j'ai trouvé sur le net porte sur une classe qui hérite de deux classes distinctes mais pas sur ce genre de shemas.

    Donc:
    Si j'instancie un objet de C et que je veuille utiliser une fonction de A sur mon objet mon compilateur me répond:
    erreur: ‘A’ is not an accessible base of ‘C’
    Est-ce qu'il peut y avoir plusieur niveaux d'héritage et si oui comment dois-je m'y prendre ensuite pour que les fonctions définies dans la classe de base reste accessible en bout de chaine?

  2. #2
    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,

    Ce qu'il faut savoir avant tout, c'est qu'un membre ou une fonction membre de la (l'une des) classe(s) de base n'est accessible à la (aux) classe(s) dérivée(s) que si l'accessibilité est protégée ou publique (et pour autant que l'héritage soit lui-même protégé ou public pour les classes "intermédiaires")

    Ainsi, si tu as une classe A du genre de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class A
    {
        public:
            void fonctionPublique();
            virtual void fonctionVirtuellePublique();
            int membrePublic;
        protected:
            void fonctionProtegee();
            virtual void fonctionVirutelleProtegee();
            int membreProtege;
    };
    et que tu as une class B qui en hérite sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class B : public A
    {
        public:
            virtual void fonctionVirtuellePublique();//redéfini le comportement pour B
        protected: 
            virtual void fonctionVirtuelleProtegee();//redéfini le comportement pour B
    };
    et, enfin, que tu as une classe C qui hérite de B sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class C : public B
    {
        public:
            virtual void fonctionVirtuellePublique();//redéfini le comportement pour C
        protected: 
            virtual void fonctionVirtuelleProtegee();//redéfini le comportement pour C
    };
    tu peux très bien en arriver à écrire un code du genre de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    int main()
    {
        A monA;
        B monB;
        C monC;
        monA.fonctionPublique();
        monB.fonctionPublique();
        monC.fonctionPublique();
        monA.membrePublic=10;
        monB.membrePublic=15;
        monC.membrePublic=20;
        /*...*/
        return 0;
    }
    Etant donné que fonctionPublique et membrePublic sont...publiques dans A, ils restent accessible depuis n'importe quel point en dehors des classes, y compris quand il s'agit d'objet de classes dérivées.

    Par contre, fonctionPortegee() et membreProtege ne seront accessible que depuis les méthodes des classes (que ce soit une méthode de B ou une méthode de C)...
    Tu ne pourrais donc pas avoir un code proche de
    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
    int main()
    {
        A monA;
        B monB;
        C monC;
        /* les six lignes suivantes provoqueront une erreur de compilation */
        monA.fonctionPortegee();
        monB.fonctionPortegee();
        monC.fonctionPortegee();
        monA.membreProtege =10;
        monB.membreProtege =15;
        monC.membreProtege =20;
        /*...*/
        return 0;
    }
    Par contre, si tu déclare une fonction membre dans C, tu peux très bien en arriver à un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void C::fonctionSupplementaire()
    {
        membreProtege=3;
        fonctionProtegee();
    }
    car une fonction membre a accès à tous les éléments qui composent la structure dont elle fait partie (hors éléments privés des classes "parentes/ancêtre" )

    enfin, il y a le cas des fonctions virtuelles...

    Le but d'une fonction virtuelle est d'adapter un comportement commun au type de l'élément réel, car ce n'est pas parce que l'on est des mammifères que nos comportements qui consistent à manger ou à nous reproduire sont identiques aux comportements que l'on observe chez un chat, un chimpanzée ou un daufin

    Ce genre de méthode permet de mettre en oeuvre ce que l'on appelle le "polymorphisme", c'est à dire que, si l'on condisère un élément comme s'il était d'un des types "ancêtres", on peut malgré tout observer le comportement du type réel:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    A *obj=new C;
    obj->fonctionVirutellePublique();//appelle le comportement propre à
                                     // C::fonctionVirtuellePublique()
    Mais, il peut arriver que la différence entre le comportement "de base" et le comportement observé dans le cadre d'une classe dérivée ne tienne que dans le fait que l'on demande d'exécuter l'une ou l'autre chose de plus dans le comportement de la classe dérivée que dans celui de la classe de base.

    Plutôt que de re coder l'ensemble du comportement, tu peux, dans une fonction membre de la classe dérivée, appeler le comportement propre à la classe de base, en précisant simplement explicitement que c'est ce que tu veux.

    Ainsi, tu pourrais envisager un code proche de
    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
    void A::fonctionVirtuellePublique()
    {
        /* ce que tu veux effectuer pour un élément de type A */
    }
    void B::fonctionVirtuellePublique()
    {
        /* ce que tu veux effectuer avant le comportement de base */
       A::fonctionVirtuellePublique();
       /* ce que tu veux effectuer apres le comportement de base */
    }
    void C::fonctionVirtuellePublique()
    {
        /* ce que tu veux effectuer avant le comportement de base */
       B::fonctionVirtuellePublique();//cela aurait pu etre 
                                      //A::fonctionVirtuellePublique()
       /* ce que tu veux effectuer apres le comportement de base */
    }
    Et, bien sur, cela aurait tout aussi bien fonctionné si on avait parlé de la même manière de fonctionVirtuelleProtegee()

    La seule chose à laquelle il faut faire attention, c'est dans le constructeur: il faut appeler le constructeur de la classe de base directe dans la liste d'initialisation
    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

  3. #3
    Membre confirmé
    Inscrit en
    Septembre 2004
    Messages
    187
    Détails du profil
    Informations forums :
    Inscription : Septembre 2004
    Messages : 187
    Par défaut
    Super!
    Merci pour ces explication limpides!

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

Discussions similaires

  1. Questions sur l'héritage multiple
    Par beegees dans le forum C++
    Réponses: 12
    Dernier message: 31/03/2008, 17h01
  2. Question sur l'héritage (débutant en C++)
    Par beegees dans le forum C++
    Réponses: 19
    Dernier message: 30/03/2008, 14h45
  3. petite question sur l'héritage et les cast
    Par baedal dans le forum Langage
    Réponses: 3
    Dernier message: 29/02/2008, 00h48
  4. Questions sur l'héritage dans Matisse
    Par Cassios dans le forum NetBeans
    Réponses: 8
    Dernier message: 14/03/2007, 23h23
  5. Question sur l'héritage
    Par the big ben 5 dans le forum Delphi
    Réponses: 28
    Dernier message: 06/06/2006, 17h27

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