Langage c++

Notification de cookies

Nous utilisons des cookies pour améliorer votre expérience. En poursuivant votre navigation sur ce site, vous acceptez l'utilisation de cookies. Plus d'informations

Héritage en C++

L'idée la plus importante de la programmation orientée objet est l'encapsulation, qui consiste à envelopper des données et des fonctions dans un seul paquet. Une autre idée puissante est l’héritage, c’est-à-dire l’idée que vous devriez pouvoir créer des classes pouvant hériter de cette encapsulation de variables membres et de fonctions d’une autre classe.

En bref, vous pouvez utiliser une abstraction dont vous disposez déjà pour créer une ou plusieurs nouvelles abstractions. Cela crée une hiérarchie: les objets peuvent hériter d'un "parent" et les relations entre divers objets hérités peuvent former une structure arborescente.

L'héritage offre plusieurs avantages.
  •   Cela évite d'avoir à réécrire le même code à plusieurs reprises. Un ancêtre peut transmettre des propriétés à tous ses descendants. En termes de codage, cela peut vous faire économiser beaucoup de temps et de travail.
  •   Cela réduit le nombre d'endroits où des bogues pourraient être introduits dans le programme, ainsi vous réduisez le temps de débogage.
  •   Il permet le polymorphisme

En pratique, l'héritage fonctionne de plusieurs manières.

D'un point de vue descendant, l'héritage orienté objet peut être considéré comme un moyen de prendre une idée plus générale et de la diviser en idées plus spécialisées. Mais l'héritage peut également fonctionner d'un point de vue ascendant, où vous commencez avec la progéniture et décidez quel type d'ancêtre ils ont en commun. Que ce soit descendant ou descendant, le résultat final est un arrangement similaire de classes.

Vous avez déjà vu quelques domaines dans lesquels l'héritage est utilisé pour définir des classes. Un domaine important concerne les flux. Vous avez vu des flux depuis et vers la console, vers et depuis des fichiers et vers et depuis des chaînes. Ce sont toutes des classes dérivées qui héritent d'une classe de base stream plus générale.

La classe dont les propriétés sont héritées par une autre classe est appelée la classe mère, Base ou superclasse. Et, la classe qui hérite des propriétés de l'autre classe s'appelle enfant ou dérivée ou sous-classe.

 Remarque ! Tous les membres d'une classe, sauf privés, sont hérités
Syntaxe :
                                class nom_sousclasse : mode_acces nom_superclasse{

                                }
                            

Lors de la définition d'une sous-classe comme celle-ci, la super-classe doit être déjà définie ou au moins déclarée avant la déclaration de la sous-classe.

Le mode d'accès est utilisé pour spécifier le mode dans lequel les propriétés de la superclasse seront héritées dans une sous-classe. Les différents modes sont public, private ou protected.

Exemple 1 :

Chaque fois que nous voulons utiliser quelque chose d'une classe existante dans une nouvelle classe, nous pouvons utiliser le concept d'héritage. Voici un exemple simple

Héritage en C++

                                    class Personne
                                    {
                                    private:
                                        int Id;
                                        char Nom[30];
                                        char Adresse[100];
                                    
                                    public:
                                        Personne(int, char[], char[]);
                                        void afficher();
                                    };
                                    
                                    class Professeur : public Personne
                                    {
                                    private:
                                        double salaire;
                                        char departement[40];
                                    
                                    public:
                                        Professeur(int, char[], char[], double, char[]);
                                    };
                                    
                                    class Etudiant : public Personne
                                    {
                                    private:
                                        char Filiere[40];
                                    
                                    public:
                                        Etudiant(int, char[], char[], char[]);
                                    };
                            

Contrôle d'accès et héritage

Une classe dérivée peut accéder à tous les membres non privés de sa classe de base. Ainsi, les membres de la classe de base qui ne devraient pas être accessibles aux fonctions membres des classes dérivées doivent être déclarés privés dans la classe de base.

Selon le modificateur d'accès utilisé pendant l'héritage, la disponibilité des membres de la classe Super class dans la sous-classe change. Il peut être soit private, protected ou public.

Nous utilisons rarement l'héritage protected ou private, mais l'héritage public est couramment utilisé. En utilisant un autre type d'héritage, les règles suivantes sont appliquées

Héritage public

Lors de la dérivation public d'une sous-classe d'une classe de base, les membres publiques de la classe de base deviennent des membres publiques de la classe dérivée et les membres protégés de la classe de base deviennent des membres protégés de la classe dérivée. Les membres privés d'une classe de base ne sont jamais accessibles directement à partir d'une classe dérivée, mais sont accessibles via des appels aux membres publiques et protégés de la classe de base.

Syntaxe:
                                class nom_sousclasse : public nom_superclasse{

                                }
                            
Héritage protected

Lors de la dérivation protected d'une sous-classe d'une classe de base, les membres publiques et protégés de la classe de base deviennent des membres protégés de la classe dérivée.

Syntaxe:
                                class nom_sousclasse : protected nom_superclasse{

                                }
                            
Héritage private

Lors de la dérivation private d'une sous-classe d'une classe de base, les membres publiques et protégés de la classe de base deviennent des membres privés de la classe dérivée.

Syntaxe:
                                class nom_sousclasse : private nom_superclasse{

                                }
                            

Nous pouvons résumer les différents types d'accès en fonction de - qui peut y accéder, de la manière suivante


Classe dérivéeClasse dérivéeClasse dérivée
Classe de baseMode publicMode privateMode protected
PrivateNon héritéNon héritéNon hérité
ProtectedProtectedPrivateProtected
PublicPublicPrivateProtected

Une classe dérivée hérite de toutes les méthodes de la classe de base avec les exceptions suivantes

  •   Constructeurs, destructeurs de la classe de base.
  •   Opérateurs surchargés de la classe de base.
  •   Les fonctions amies de la classe de base.

Types d'héritage en C++

En C ++, nous avons 5 types différents d'héritage. À savoir,

  •  Héritage simple
  •  Héritage multiple
  •  Héritage hiérarchique
  •  Héritage à plusieurs niveaux
  •  Héritage hybride (également appelé héritage virtuel)

Héritage simple

Dans ce type d'héritage, une classe dérivée hérite d'une seule classe de base. C'est la forme la plus simple de l'héritage.

Héritage simple

                                    class Personne
                                    {
                                        private:
                                            int Id;
                                            char Nom[30];
                                            char Adresse[100];
                                    
                                        public:
                                            Personne(int, char[], char[]);
                                            void afficher();
                                    };
                                    class Etudiant : public Personne
                                    {
                                        private:
                                            char Filiere[40];

                                        public:
                                            Etudiant(int, char[], char[], char[]);
                                    };
                            

Héritage multiple

Dans ce type d'héritage, une seule classe dérivée peut hériter de deux ou plus de deux classes de base.

Héritage multiple

                                class ProfAssistant : public Etudiant, public Professeur
                                {
                                        
                                };
                            

Héritage hiérarchique

Dans ce type d'héritage, une classe de base a plus d'une classe enfant. Par exemple:

Héritage hiérarchique

                                    class Personne
                                    {
                                    private:
                                        int Id;
                                        char Nom[30];
                                        char Adresse[100];
                                    
                                    public:
                                        Personne(int, char[], char[]);
                                        void afficher();
                                    };
                                    
                                    class Professeur : public Personne
                                    {
                                    private:
                                        double salaire;
                                        char departement[40];
                                    
                                    public:
                                        Professeur(int, char[], char[], double, char[]);
                                    };
                                    
                                    class Etudiant : public Personne
                                    {
                                    private:
                                        char Filiere[40];
                                    
                                    public:
                                        Etudiant(int, char[], char[], char[]);
                                    };
                            

Héritage à plusieurs niveaux

Dans ce type d'héritage, la classe dérivée hérite d'une classe, qui hérite à son tour d'une autre classe. La classe de base pour l'une est la sous-classe pour l'autre.

Héritage à plusieurs niveaux

                                    class Personne
                                    {
                                        private:
                                            int Id;
                                            char Nom[30];
                                            char Adresse[100];
                                    
                                        public:
                                            Personne(int, char[], char[]);
                                            void afficher();
                                    };
                                    class Etudiant : public Personne
                                    {
                                        private:
                                            char Filiere[40];

                                        public:
                                            Etudiant(int, char[], char[], char[]);
                                    };
                                    class EtudiantInterne : public Etudiant
                                    {
                                        public:
                                            EtudiantInterne(int, char[], char[], char[]);
                                    };
                            

Héritage hybride

L'héritage hybride est une combinaison d'héritage hiérarchique et d'héritage multiniveau.

Héritage hybride

                                    class Personne
                                    {
                                        private:
                                            int Id;
                                            char Nom[30];
                                            char Adresse[100];
                                    
                                        public:
                                            Personne(int, char[], char[]);
                                            void afficher();
                                    };
                                    class Professeur : public Personne
                                    {
                                        private:
                                            double salaire;
                                            char departement[40];
                                    
                                        public:
                                            Professeur(int, char[], char[], double, char[]);
                                    };
                                    class Etudiant : public Personne
                                    {
                                        private:
                                            char Filiere[40];

                                        public:
                                            Etudiant(int, char[], char[], char[]);
                                    };
                                    class ProfAssistant : public Etudiant, public Professeur
                                    {
                                        public:
                                            ProfAssistant(int, char[], char[], char[], double, char[]);
                                    };
                            

Ordre d'appel du constructeur

Les constructeurs de classe de base sont toujours appelés dans les constructeurs de classe dérivés. Chaque fois que vous créez un objet de classe dérivée, le constructeur par défaut de la classe de base est d'abord exécuté, puis le constructeur de la classe dérivée termine son exécution.

Points à retenir
  •   Que le constructeur par défaut de la classe dérivée soit appelé ou paramétré, le constructeur par défaut de la classe de base est toujours appelé à l'intérieur de ceux-ci.
  •   Pour appeler le constructeur paramétré de la classe de base à l'intérieur du constructeur paramétré de la classe dérivée, il faut le mentionner explicitement lors de la déclaration du constructeur paramétré de la classe dérivée.

Constructeur par défaut de la classe de base dans les constructeurs de la classe dérivée

Un constructeur par défaut est présent dans toutes les classes. Dans l'exemple ci-dessous, nous verrons quand et pourquoi les constructeurs de la classe Base et de la classe dérivée sont appelés.

Exemple 2 :
                                    #include <iostream>
                                    using namespace std;
                                    
                                    class Base
                                    {
                                        int x;
                                    
                                    public:
                                        // Constructeur par défaut
                                        Base()
                                        {
                                            cout << "Constructeur par défaut de la classe de base\n";
                                        }
                                    };
                                    
                                    class Herite : public Base
                                    {
                                        int y;
                                    
                                    public:
                                        // Constructeur par défaut
                                        Herite()
                                        {
                                            cout << "Constructeur par défaut de la classe derivée\n";
                                        }
                                        // Constructeur paramétré
                                        Herite(int i)
                                        {
                                            cout << "Constructeur paramétré de la classe derivée\n";
                                        }
                                    };
                                    
                                    int main()
                                    {
                                        Herite d1;
                                        Herite d2(10);
                                    }
                            

Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant

Constructeur par défaut de la classe de base
Constructeur par défaut de la classe derivée
Constructeur par défaut de la classe de base
Constructeur paramétré de la classe derivée

Vous avez vu dans l'exemple ci-dessus qu'avec la création d'objet de la classe dérivée, le constructeur par défaut de la classe de base est appelé.

Constructeur paramétré de classe de base dans constructeur de classe dérivée

Nous pouvons explicitement mentionner l'appel du constructeur paramétré de la classe Base lorsque le constructeur paramétré de la classe dérivée est appelé.

Exemple 3 :
                                    #include <iostream>
                                    using namespace std;
                                    
                                    class Base
                                    {
                                        int x;
                                    
                                    public:
                                        // Constructeur paramétré
                                        Base(int i)
                                        {
                                            x = i;
                                            cout << "Constructeur paramétré de la classe de base\n";
                                        }
                                    };
                                    
                                    class Herite : public Base
                                    {
                                        int y;
                                    
                                    public:
                                        // Constructeur paramétré
                                        Herite(int i) : Base(i)
                                        {
                                            cout << "Constructeur paramétré de la classe derivée\n";
                                        }
                                    };
                                    
                                    int main()
                                    {
                                        Herite d(10);
                                    }
                            

Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant

Constructeur paramétré de la classe de base
Constructeur paramétré de la classe derivée

Pourquoi le constructeur de la classe de base est-il appelé dans la classe dérivée ?

Les constructeurs ont pour tâche d'initialiser correctement l'objet. Un constructeur de classe dérivée n'a accès qu'à ses propres membres, mais un objet de classe dérivée possède également la propriété héritée de la classe de base et seul le constructeur de la classe de base peut initialiser correctement les membres de la classe de base. Par conséquent, tous les constructeurs sont appelés, sinon l'objet ne serait pas construit correctement.

Appel de constructeur en héritage multiple en C++

C'est presque pareil, tous les constructeurs de la classe de base sont appelés à l'intérieur du constructeur de la classe dérivée, dans le même ordre dans lequel ils sont hérités.

Exemple 4 :
                                class A : public B, public C ;
                            

Dans ce cas, le constructeur de première classe B sera exécuté, puis le constructeur de classe C, puis le constructeur de classe A.

Partager ce cours avec tes amis :

Rédigé par M. ESSADDOUKI

Learning a new programming language is an easy thing, but the most difficult thing is how to design efficient algorithms for real-world problems, so don't be a programmer, be a problems solver.

Cours Similaires :