La capacité d'un classe pour dériver des propriétés et des caractéristiques d'une autre classe est appelé Héritage . L'héritage est l'une des fonctionnalités les plus importantes de la programmation orientée objet.
L'héritage est une fonctionnalité ou un processus dans lequel de nouvelles classes sont créées à partir des classes existantes. La nouvelle classe créée est appelée classe dérivée ou classe enfant et la classe existante est appelée classe de base ou classe parent. On dit maintenant que la classe dérivée est héritée de la classe de base.
Lorsque nous disons que la classe dérivée hérite de la classe de base, cela signifie que la classe dérivée hérite de toutes les propriétés de la classe de base, sans modifier les propriétés de la classe de base et peut ajouter de nouvelles fonctionnalités aux siennes. Ces nouvelles fonctionnalités dans la classe dérivée n’affecteront pas la classe de base. La classe dérivée est la classe spécialisée de la classe de base.
- Sous-classe : La classe qui hérite des propriétés d'une autre classe est appelée sous-classe ou classe dérivée.
- Super Classe : La classe dont les propriétés sont héritées par une sous-classe est appelée classe de base ou superclasse.
L'article est divisé en sous-thèmes suivants :
- Pourquoi et quand recourir à l’héritage ?
- Modes d'héritage
- Types d'héritage
Pourquoi et quand recourir à l’héritage ?
Prenons un groupe de véhicules. Vous devez créer des classes pour Bus, Voiture et Camion. Les méthodes fuelAmount(), capacité(), applyBrakes() seront les mêmes pour les trois classes. Si nous créons ces classes en évitant l'héritage, nous devons alors écrire toutes ces fonctions dans chacune des trois classes, comme indiqué dans la figure ci-dessous :

maître d'origine git pull
Vous pouvez clairement voir que le processus ci-dessus entraîne la duplication du même code 3 fois. Cela augmente les risques d'erreur et de redondance des données. Pour éviter ce type de situation, l'héritage est utilisé. Si nous créons une classe Vehicle et y écrivons ces trois fonctions et héritons du reste des classes de la classe Vehicle, nous pouvons alors simplement éviter la duplication des données et augmenter la réutilisation. Regardez le diagramme ci-dessous dans lequel les trois classes sont héritées de la classe du véhicule :

En utilisant l'héritage, nous devons écrire les fonctions une seule fois au lieu de trois fois car nous avons hérité du reste des trois classes de la classe de base (Vehicle).
Implémentation de l'héritage en C++ : Pour créer une sous-classe héritée de la classe de base, nous devons suivre la syntaxe ci-dessous.
Classes dérivées : Une classe dérivée est définie comme la classe dérivée de la classe de base.
Syntaxe :
class : { //body }>Où
class — mot-clé pour créer une nouvelle classe
dérivé_class_name — nom de la nouvelle classe, qui héritera de la classe de base
spécificateur d'accès - soit privé, public ou protégé. Si aucun des deux n'est spécifié, PRIVATE est pris par défaut
base-class-name — nom de la classe de base
Note : Une classe dérivée n’hérite pas accéder aux membres de données privées. Cependant, il hérite d'un objet parent complet, qui contient tous les membres privés déclarés par cette classe.
Exemple:
1. classe ABC : XYZ privé //dérivation privée
{ }
2. classe ABC : public XYZ //dérivation publique
{ }
3. classe ABC : XYZ protégé //dérivation protégée
{ }
4. classe ABC : XYZ //dérivation privée par défaut
{ }
Note:
o Lorsqu'une classe de base est héritée de manière privée par la classe dérivée, les membres publics de la classe de base deviennent les membres privés de la classe dérivée et, par conséquent, les membres publics de la classe de base ne sont accessibles que par les fonctions membres de la classe dérivée. Ils sont inaccessibles aux objets de la classe dérivée.
o D'un autre côté, lorsque la classe de base est publiquement héritée par la classe dérivée, les membres publics de la classe de base deviennent également les membres publics de la classe dérivée. Par conséquent, les membres publics de la classe de base sont accessibles par les objets de la classe dérivée ainsi que par les fonctions membres de la classe dérivée.
// Example: define member function without argument within // the class #include using namespace std; class Person { int id; char name[100]; public: void set_p() { cout << 'Enter the Id:'; cin>> identifiant ; cout<< 'Enter the Name:'; cin>> nom ; } void display_p() { cout<< endl <<'Id: '<< id << '
Name: ' << name <> cours ; cout<< 'Enter the Course Fee:'; cin>> frais ; } void display_s() { display_p(); cout<<'Course: '<< course << '
Fee: ' << fee << endl; } }; int main() { Student s; s.set_s(); s.display_s(); return 0; }> Sortir:
où puis-je trouver les paramètres de mon navigateur
Enter the Id: 101 Enter the Name: Dev Enter the Course Name: GCS Enter the Course Fee:70000 Id: 101 Name: Dev Course: GCS Fee: 70000>C++
// Example: define member function without argument outside the class #include using namespace std; class Person { int id; char name[100]; public: void set_p(); void display_p(); }; void Person::set_p() { cout<<'Enter the Id:'; cin>>identifiant ; cout<<'Enter the Name:'; cin>>nom ; } void Person::display_p() { cout<>cours ; cout<<'Enter the Course Fee:'; cin>>frais ; } void Student::display_s() { display_p(); cout<<'
Course: '< Sortir:
Enter the Id: 101 Enter the Name: Dev Enter the Course Name: GCS Enter the Course Fee: 70000 Id: 101 Name: Dev Course: GCS Fee: 70000>C++
// Example: define member function with argument outside the class #include #include using namespace std; class Person { int id; char name[100]; public: void set_p(int,char[]); void display_p(); }; void Person::set_p(int id,char n[]) { this->identifiant=identifiant ; strcpy(this->name,n); } void Person::display_p() { cout< RPC
// C++ program to demonstrate implementation // of Inheritance #include using namespace std; // Base class class Parent { public: int id_p; }; // Sub class inheriting from Base Class(Parent) class Child : public Parent { public: int id_c; }; // main function int main() { Child obj1; // An object of class child has all data members // and member functions of class parent obj1.id_c = 7; obj1.id_p = 91; cout << 'Child id is: ' << obj1.id_c << '
'; cout << 'Parent id is: ' << obj1.id_p << '
'; return 0; }> Sortir
Child id is: 7 Parent id is: 91>
Dans le programme ci-dessus, la classe « Enfant » est publiquement héritée de la classe « Parent », de sorte que les données publiques membres de la classe « Parent » seront également héritées par la classe « Enfant ».
Modes d'héritage : Il existe 3 modes d'héritage.
- Mode public : Si nous dérivons une sous-classe d'une classe de base publique. Ensuite, le membre public de la classe de base deviendra public dans la classe dérivée et les membres protégés de la classe de base deviendront protégés dans la classe dérivée.
- Mode protégé : Si nous dérivons une sous-classe d’une classe de base protégée. Ensuite, les membres publics et les membres protégés de la classe de base deviendront protégés dans la classe dérivée.
- Mode privé : Si nous dérivons une sous-classe d’une classe de base privée. Ensuite, les membres publics et les membres protégés de la classe de base deviendront Private dans la classe dérivée.
Note: Les membres privés de la classe de base ne sont pas directement accessibles dans la classe dérivée, tandis que les membres protégés sont directement accessibles. Par exemple, les classes B, C et D contiennent toutes les variables x, y et z dans l'exemple ci-dessous. C'est juste une question d'accès.
RPC // C++ Implementation to show that a derived class // doesn’t inherit access to private data members. // However, it does inherit a full parent object. class A { public: int x; protected: int y; private: int z; }; class B : public A { // x is public // y is protected // z is not accessible from B }; class C : protected A { // x is protected // y is protected // z is not accessible from C }; class D : private A // 'private' is default for classes { // x is private // y is private // z is not accessible from D };>
Le tableau ci-dessous résume les trois modes ci-dessus et montre le spécificateur d'accès des membres de la classe de base dans la sous-classe lorsqu'ils sont dérivés en modes public, protégé et privé :

Types d'héritage : -
- Héritage unique
- Héritage multiniveau
- Héritage multiple
- Héritage hiérarchique
- Héritage hybride
Types d'héritage en C++
1. Héritage unique : En héritage simple, une classe est autorisée à hériter d’une seule classe. c'est-à-dire qu'une sous-classe est héritée par une seule classe de base.

Syntaxe :
class subclass_name : access_mode base_class { // body of subclass }; OR class A { ... .. ... }; class B: public A { ... .. ... };>RPC // C++ program to explain // Single inheritance #include using namespace std; // base class class Vehicle { public: Vehicle() { cout << 'This is a Vehicle
'; } }; // sub class derived from a single base classes class Car : public Vehicle { }; // main function int main() { // Creating object of sub class will // invoke the constructor of base classes Car obj; return 0; }> Sortir
This is a Vehicle>
C++
// Example: #include using namespace std; class A { protected: int a; public: void set_A() { cout<<'Enter the Value of A='; cin>>une ; } void disp_A() { cout< Sortie : - Entrez la valeur de A= 3 3 Entrez la valeur de B= 5 5 Produit de 3 * 5 = 15
C++
// Example: #include using namespace std; class A { protected: int a; public: void set_A(int x) { a=x; } void disp_A() { cout< Sortir
Product of 4 * 5 = 20>
2. Héritage multiple : L'héritage multiple est une fonctionnalité du C++ où une classe peut hériter de plusieurs classes. c'est à dire un sous-classe est hérité de plus d'un classe de base .

Syntaxe :
class subclass_name : access_mode base_class1, access_mode base_class2, .... { // body of subclass }; class B { ... .. ... }; class C { ... .. ... }; class A: public B, public C { ... ... ... };>Ici, le nombre de classes de base sera séparé par une virgule (', ') et le mode d'accès pour chaque classe de base doit être spécifié.
RPC // C++ program to explain // multiple inheritance #include using namespace std; // first base class class Vehicle { public: Vehicle() { cout << 'This is a Vehicle
'; } }; // second base class class FourWheeler { public: FourWheeler() { cout << 'This is a 4 wheeler Vehicle
'; } }; // sub class derived from two base classes class Car : public Vehicle, public FourWheeler { }; // main function int main() { // Creating object of sub class will // invoke the constructor of base classes. Car obj; return 0; }> Sortir
This is a Vehicle This is a 4 wheeler Vehicle>
C++
// Example: #include using namespace std; class A { protected: int a; public: void set_A() { cout<<'Enter the Value of A='; cin>>une ; } void disp_A() { cout<
Pour en savoir plus, veuillez vous référer à l'article Héritages multiples .
3. Héritage à plusieurs niveaux : Dans ce type d'héritage, une classe dérivée est créée à partir d'une autre classe dérivée.

réseaux informatiques
Syntaxe:-
class C { ... .. ... }; class B:public C { ... .. ... }; class A: public B { ... ... ... };>RPC // C++ program to implement // Multilevel Inheritance #include using namespace std; // base class class Vehicle { public: Vehicle() { cout << 'This is a Vehicle
'; } }; // first sub_class derived from class vehicle class fourWheeler : public Vehicle { public: fourWheeler() { cout << 'Objects with 4 wheels are vehicles
'; } }; // sub class derived from the derived base class fourWheeler class Car : public fourWheeler { public: Car() { cout << 'Car has 4 Wheels
'; } }; // main function int main() { // Creating object of sub class will // invoke the constructor of base classes. Car obj; return 0; }> Sortir
This is a Vehicle Objects with 4 wheels are vehicles Car has 4 Wheels>
4. Héritage hiérarchique : Dans ce type d'héritage, plusieurs sous-classes sont héritées d'une seule classe de base. c'est-à-dire que plusieurs classes dérivées sont créées à partir d'une seule classe de base.

'abc' est en chiffres'
Syntaxe:-
class A { // body of the class A. } class B : public A { // body of class B. } class C : public A { // body of class C. } class D : public A { // body of class D. }>RPC // C++ program to implement // Hierarchical Inheritance #include using namespace std; // base class class Vehicle { public: Vehicle() { cout << 'This is a Vehicle
'; } }; // first sub class class Car : public Vehicle { }; // second sub class class Bus : public Vehicle { }; // main function int main() { // Creating object of sub class will // invoke the constructor of base class. Car obj1; Bus obj2; return 0; }> Sortir
This is a Vehicle This is a Vehicle>
5. Héritage hybride (virtuel) : L'héritage hybride est mis en œuvre en combinant plusieurs types d'héritage. Par exemple : combiner l'héritage hiérarchique et l'héritage multiple.
L'image ci-dessous montre la combinaison d'héritages hiérarchiques et multiples :

// C++ program for Hybrid Inheritance #include using namespace std; // base class class Vehicle { public: Vehicle() { cout << 'This is a Vehicle
'; } }; // base class class Fare { public: Fare() { cout << 'Fare of Vehicle
'; } }; // first sub class class Car : public Vehicle { }; // second sub class class Bus : public Vehicle, public Fare { }; // main function int main() { // Creating object of sub class will // invoke the constructor of base class. Bus obj2; return 0; }> Sortir
This is a Vehicle Fare of Vehicle>C++
// Example: #include using namespace std; class A { protected: int a; public: void get_a() { cout << 'Enter the value of 'a' : '; cin>>une ; } } ; classe B : public A { protégé : int b ; public : void get_b() { cout<< 'Enter the value of 'b' : '; cin>>b; } } ; classe C { protégé : int c ; public : void get_c() { cout<< 'Enter the value of c is : '; cin>>c; } } ; classe D : public B, public C { protégé : int d ; public : void mul() { get_a(); get_b(); get_c(); cout<< 'Multiplication of a,b,c is : ' <
6. Un cas particulier d'héritage hybride : l'héritage multipath :
Une classe dérivée avec deux classes de base et ces deux classes de base ont une classe de base commune est appelée héritage multipath. Des ambiguïtés peuvent surgir dans ce type d’héritage.
Exemple:
// C++ program demonstrating ambiguity in Multipath // Inheritance #include using namespace std; class ClassA { public: int a; }; class ClassB : public ClassA { public: int b; }; class ClassC : public ClassA { public: int c; }; class ClassD : public ClassB, public ClassC { public: int d; }; int main() { ClassD obj; // obj.a = 10; // Statement 1, Error // obj.a = 100; // Statement 2, Error obj.ClassB::a = 10; // Statement 3 obj.ClassC::a = 100; // Statement 4 obj.b = 20; obj.c = 30; obj.d = 40; cout << ' a from ClassB : ' << obj.ClassB::a; cout << '
a from ClassC : ' << obj.ClassC::a; cout << '
b : ' << obj.b; cout << '
c : ' << obj.c; cout << '
d : ' << obj.d << '
'; }> Sortir
a from ClassB : 10 a from ClassC : 100 b : 20 c : 30 d : 40>
Dans l'exemple ci-dessus, ClassB et ClassC héritent de ClassA, ils ont tous deux une seule copie de ClassA. Cependant, Class-D hérite à la fois de ClassB et de ClassC, donc Class-D possède deux copies de ClassA, une de ClassB et une autre de ClassC.
Si nous devons accéder aux données membres de ClassA via l'objet de Class-D, nous devons spécifier le chemin à partir duquel a sera accessible, qu'il s'agisse de ClassB ou de ClassC, le compilateur bcoz ne peut pas faire la différence entre deux copies de ClassA dans Classe-D.
Il existe 2 façons d’éviter cette ambiguïté :
1) Éviter toute ambiguïté à l'aide de l'opérateur de résolution de portée : À l'aide de l'opérateur de résolution de portée, nous pouvons spécifier manuellement le chemin à partir duquel le membre de données a sera accessible, comme indiqué dans les instructions 3 et 4, dans l'exemple ci-dessus.
RPC obj.ClassB::a = 10; // Statement 3 obj.ClassC::a = 100; // Statement 4>
Note: Pourtant, il existe deux copies de ClassA en Class-D.
2) Éviter toute ambiguïté en utilisant la classe de base virtuelle :
#include class ClassA { public: int a; }; class ClassB : virtual public ClassA { public: int b; }; class ClassC : virtual public ClassA { public: int c; }; class ClassD : public ClassB, public ClassC { public: int d; }; int main() { ClassD obj; obj.a = 10; // Statement 3 obj.a = 100; // Statement 4 obj.b = 20; obj.c = 30; obj.d = 40; cout << '
a : ' << obj.a; cout << '
b : ' << obj.b; cout << '
c : ' << obj.c; cout << '
d : ' << obj.d << '
'; }> Sortir:
a : 100 b : 20 c : 30 d : 40>
Selon l'exemple ci-dessus, Class-D n'a qu'une seule copie de ClassA, par conséquent, l'instruction 4 écrasera la valeur de a, donnée dans l'instruction 3.