Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Apprendre Héritage en Diamant | Aperçu de l'Héritage
Programmation Orientée Objet en C++
course content

Contenu du cours

Programmation Orientée Objet en C++

Programmation Orientée Objet en C++

1. Fondamentaux de la POO en C++
2. Constructeurs et Destructeurs
3. Aperçu de l'Encapsulation
4. Aperçu de l'Héritage
5. Aperçu du Polymorphisme

book
Héritage en Diamant

L'héritage multiple peut conduire à une situation connue sous le nom de problème du diamant ou héritage en diamant, qui constitue un défi majeur dans les langages de programmation orientés objet prenant en charge l'héritage multiple.

Cela se produit lorsqu'une sous-classe hérite de deux ou plusieurs classes, qui elles-mêmes héritent d'une superclasse commune. Le terme diamant est utilisé car le schéma d'héritage ressemble à la forme d'un diamant.

main.cpp

main.cpp

copy
1234567
class Base {}; class Derived1 : public Base {}; class Derived2 : public Base {}; class Diamond : public Derived1, public Derived2 {};

Le principal problème de l'héritage en diamant est l'ambiguïté qu'il engendre. Puisque Diamond hérite à la fois de Derived1 et de Derived2, qui héritent eux-mêmes de Base, il existe deux copies de Base dans un objet de type Diamond. Cela peut entraîner une ambiguïté.

main.cpp

main.cpp

copy
12345678910111213141516
#include <iostream> class Base { public: void display() { std::cout << "Base display()" << std::endl; } }; class Derived1 : public Base { }; class Derived2 : public Base { }; class Diamond : public Derived1, public Derived2 { }; int main() { Diamond obj; obj.display(); // Ambiguity: Which display() method should be called? }

Solution au problème

Le mot-clé virtual permet d'éviter ce problème. Vous pouvez résoudre cette ambiguïté grâce à l'héritage virtuel en utilisant le mot-clé virtual. Lorsque Diamond hérite virtuellement, C++ garantit qu'une seule copie de la superclasse est présente, même si elle est héritée plusieurs fois via différents chemins.

main.cpp

main.cpp

copy
1234567
class Base {}; class Derived1 : virtual public Base {}; class Derived2 : virtual public Base {}; class Diamond : public Derived1, public Derived2 {};
Note
Remarque

Essayez de résoudre le problème d'ambiguïté dans l'exemple précédent en utilisant l'héritage virtuel.

Implémentation de l'héritage en diamant

Pour implémenter efficacement l'héritage en diamant, utiliser le mot-clé virtual dans la déclaration de la superclasse au sein des classes intermédiaires. Assurer une utilisation cohérente de l'héritage virtuel dans tous les chemins de la hiérarchie d'héritage, et prêter attention à l'ordre d'appel des constructeurs et destructeurs.

Résolution des ambiguïtés

L'un des défis de l'héritage multiple consiste également à gérer les ambiguïtés potentielles concernant les membres portant les mêmes noms.

main.cpp

main.cpp

copy
12345678910111213141516171819
#include <iostream> class Base {}; class Derived1 : public Base { public: void display() { std::cout << "Derived1 display()" << std::endl; } }; class Derived2 : public Base { public: void display() { std::cout << "Derived2 display()" << std::endl; } }; class Diamond : public Derived1, public Derived2 { }; int main() { Diamond obj; obj.display(); // Ambiguity: Which display() method should be called? }

Si les deux superclasses possèdent des membres portant le même nom, la sous-classe peut ne pas savoir lequel utiliser. Pour résoudre de telles ambiguïtés, il est possible d'utiliser l'opérateur de résolution de portée (::) afin de spécifier le membre de la classe de base que vous souhaitez accéder. Par exemple :

main.cpp

main.cpp

copy
1234567891011121314151617181920
#include <iostream> class Base {}; class Derived1 : public Base { public: void display() { std::cout << "Derived1 display()" << std::endl; } }; class Derived2 : public Base { public: void display() { std::cout << "Derived2 display()" << std::endl; } }; class Diamond : public Derived1, public Derived2 { }; int main() { Diamond obj; obj.Derived1::display(); obj.Derived2::display(); }
question mark

Quel est le principal problème causé par l'héritage en diamant ?

Select the correct answer

Tout était clair ?

Comment pouvons-nous l'améliorer ?

Merci pour vos commentaires !

Section 4. Chapitre 5

Demandez à l'IA

expand

Demandez à l'IA

ChatGPT

Posez n'importe quelle question ou essayez l'une des questions suggérées pour commencer notre discussion

course content

Contenu du cours

Programmation Orientée Objet en C++

Programmation Orientée Objet en C++

1. Fondamentaux de la POO en C++
2. Constructeurs et Destructeurs
3. Aperçu de l'Encapsulation
4. Aperçu de l'Héritage
5. Aperçu du Polymorphisme

book
Héritage en Diamant

L'héritage multiple peut conduire à une situation connue sous le nom de problème du diamant ou héritage en diamant, qui constitue un défi majeur dans les langages de programmation orientés objet prenant en charge l'héritage multiple.

Cela se produit lorsqu'une sous-classe hérite de deux ou plusieurs classes, qui elles-mêmes héritent d'une superclasse commune. Le terme diamant est utilisé car le schéma d'héritage ressemble à la forme d'un diamant.

main.cpp

main.cpp

copy
1234567
class Base {}; class Derived1 : public Base {}; class Derived2 : public Base {}; class Diamond : public Derived1, public Derived2 {};

Le principal problème de l'héritage en diamant est l'ambiguïté qu'il engendre. Puisque Diamond hérite à la fois de Derived1 et de Derived2, qui héritent eux-mêmes de Base, il existe deux copies de Base dans un objet de type Diamond. Cela peut entraîner une ambiguïté.

main.cpp

main.cpp

copy
12345678910111213141516
#include <iostream> class Base { public: void display() { std::cout << "Base display()" << std::endl; } }; class Derived1 : public Base { }; class Derived2 : public Base { }; class Diamond : public Derived1, public Derived2 { }; int main() { Diamond obj; obj.display(); // Ambiguity: Which display() method should be called? }

Solution au problème

Le mot-clé virtual permet d'éviter ce problème. Vous pouvez résoudre cette ambiguïté grâce à l'héritage virtuel en utilisant le mot-clé virtual. Lorsque Diamond hérite virtuellement, C++ garantit qu'une seule copie de la superclasse est présente, même si elle est héritée plusieurs fois via différents chemins.

main.cpp

main.cpp

copy
1234567
class Base {}; class Derived1 : virtual public Base {}; class Derived2 : virtual public Base {}; class Diamond : public Derived1, public Derived2 {};
Note
Remarque

Essayez de résoudre le problème d'ambiguïté dans l'exemple précédent en utilisant l'héritage virtuel.

Implémentation de l'héritage en diamant

Pour implémenter efficacement l'héritage en diamant, utiliser le mot-clé virtual dans la déclaration de la superclasse au sein des classes intermédiaires. Assurer une utilisation cohérente de l'héritage virtuel dans tous les chemins de la hiérarchie d'héritage, et prêter attention à l'ordre d'appel des constructeurs et destructeurs.

Résolution des ambiguïtés

L'un des défis de l'héritage multiple consiste également à gérer les ambiguïtés potentielles concernant les membres portant les mêmes noms.

main.cpp

main.cpp

copy
12345678910111213141516171819
#include <iostream> class Base {}; class Derived1 : public Base { public: void display() { std::cout << "Derived1 display()" << std::endl; } }; class Derived2 : public Base { public: void display() { std::cout << "Derived2 display()" << std::endl; } }; class Diamond : public Derived1, public Derived2 { }; int main() { Diamond obj; obj.display(); // Ambiguity: Which display() method should be called? }

Si les deux superclasses possèdent des membres portant le même nom, la sous-classe peut ne pas savoir lequel utiliser. Pour résoudre de telles ambiguïtés, il est possible d'utiliser l'opérateur de résolution de portée (::) afin de spécifier le membre de la classe de base que vous souhaitez accéder. Par exemple :

main.cpp

main.cpp

copy
1234567891011121314151617181920
#include <iostream> class Base {}; class Derived1 : public Base { public: void display() { std::cout << "Derived1 display()" << std::endl; } }; class Derived2 : public Base { public: void display() { std::cout << "Derived2 display()" << std::endl; } }; class Diamond : public Derived1, public Derived2 { }; int main() { Diamond obj; obj.Derived1::display(); obj.Derived2::display(); }
question mark

Quel est le principal problème causé par l'héritage en diamant ?

Select the correct answer

Tout était clair ?

Comment pouvons-nous l'améliorer ?

Merci pour vos commentaires !

Section 4. Chapitre 5
some-alt