Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Leer Diamant-erfenis | Overzicht van Overerving
C++ OOP
course content

Cursusinhoud

C++ OOP

C++ OOP

1. Fundamenten van OOP in C++
2. Constructors en Destructors
3. Overzicht van Encapsulatie
4. Overzicht van Overerving
5. Overzicht van Polymorfisme

book
Diamant-erfenis

Meervoudige overerving kan leiden tot een situatie die bekend staat als het diamond-probleem of diamond-inheritance, wat een aanzienlijke uitdaging vormt in objectgeoriënteerde programmeertalen die meervoudige overerving ondersteunen.

Dit doet zich voor wanneer een subklasse erft van twee of meer classes, die op hun beurt erven van een gemeenschappelijke superklasse. De term diamond wordt gebruikt omdat het overervingsschema de vorm van een diamant heeft.

main.cpp

main.cpp

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

Het belangrijkste probleem bij diamond-inheritance is de ambiguïteit die het veroorzaakt. Omdat Diamond erft van zowel Derived1 als Derived2, die op hun beurt erven van Base, zijn er twee kopieën van Base binnen een object van Diamond. Dit kan leiden tot ambiguïteit.

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? }

Oplossing voor het probleem

Het sleutelwoord virtual helpt om dit probleem te voorkomen. U kunt deze onduidelijkheid oplossen via virtuele overerving door het sleutelwoord virtual te gebruiken. Wanneer Diamond virtueel erft, zorgt C++ ervoor dat er slechts één kopie van de superklasse aanwezig is, zelfs als deze via verschillende paden meerdere keren wordt geërfd.

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
Opmerking

Probeer het ambiguïteitsprobleem in het vorige voorbeeld op te lossen door gebruik te maken van virtuele overerving.

Implementatie van Diamond Inheritance

Voor een effectieve implementatie van diamond inheritance, gebruik het virtual-keyword in de superklasse-declaratie binnen de tussenliggende classes. Zorg voor consistente toepassing van virtuele overerving in alle paden van de overervingshiërarchie en let op de volgorde van aanroepen van constructors en destructors.

Oplossen van ambiguïteiten

Een van de uitdagingen van meervoudige overerving is het omgaan met mogelijke ambiguïteiten bij leden met dezelfde namen.

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? }

Als beide superklassen leden met dezelfde naam hebben, weet de subklasse mogelijk niet welke gebruikt moet worden. Om dergelijke ambiguïteiten op te lossen, kun je de scope-resolutie-operator (::) gebruiken om aan te geven van welke basisklasse je het lid wilt benaderen. Bijvoorbeeld:

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

Wat is het belangrijkste probleem veroorzaakt door diamond inheritance?

Select the correct answer

Was alles duidelijk?

Hoe kunnen we het verbeteren?

Bedankt voor je feedback!

Sectie 4. Hoofdstuk 5

Vraag AI

expand

Vraag AI

ChatGPT

Vraag wat u wilt of probeer een van de voorgestelde vragen om onze chat te starten.

course content

Cursusinhoud

C++ OOP

C++ OOP

1. Fundamenten van OOP in C++
2. Constructors en Destructors
3. Overzicht van Encapsulatie
4. Overzicht van Overerving
5. Overzicht van Polymorfisme

book
Diamant-erfenis

Meervoudige overerving kan leiden tot een situatie die bekend staat als het diamond-probleem of diamond-inheritance, wat een aanzienlijke uitdaging vormt in objectgeoriënteerde programmeertalen die meervoudige overerving ondersteunen.

Dit doet zich voor wanneer een subklasse erft van twee of meer classes, die op hun beurt erven van een gemeenschappelijke superklasse. De term diamond wordt gebruikt omdat het overervingsschema de vorm van een diamant heeft.

main.cpp

main.cpp

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

Het belangrijkste probleem bij diamond-inheritance is de ambiguïteit die het veroorzaakt. Omdat Diamond erft van zowel Derived1 als Derived2, die op hun beurt erven van Base, zijn er twee kopieën van Base binnen een object van Diamond. Dit kan leiden tot ambiguïteit.

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? }

Oplossing voor het probleem

Het sleutelwoord virtual helpt om dit probleem te voorkomen. U kunt deze onduidelijkheid oplossen via virtuele overerving door het sleutelwoord virtual te gebruiken. Wanneer Diamond virtueel erft, zorgt C++ ervoor dat er slechts één kopie van de superklasse aanwezig is, zelfs als deze via verschillende paden meerdere keren wordt geërfd.

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
Opmerking

Probeer het ambiguïteitsprobleem in het vorige voorbeeld op te lossen door gebruik te maken van virtuele overerving.

Implementatie van Diamond Inheritance

Voor een effectieve implementatie van diamond inheritance, gebruik het virtual-keyword in de superklasse-declaratie binnen de tussenliggende classes. Zorg voor consistente toepassing van virtuele overerving in alle paden van de overervingshiërarchie en let op de volgorde van aanroepen van constructors en destructors.

Oplossen van ambiguïteiten

Een van de uitdagingen van meervoudige overerving is het omgaan met mogelijke ambiguïteiten bij leden met dezelfde namen.

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? }

Als beide superklassen leden met dezelfde naam hebben, weet de subklasse mogelijk niet welke gebruikt moet worden. Om dergelijke ambiguïteiten op te lossen, kun je de scope-resolutie-operator (::) gebruiken om aan te geven van welke basisklasse je het lid wilt benaderen. Bijvoorbeeld:

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

Wat is het belangrijkste probleem veroorzaakt door diamond inheritance?

Select the correct answer

Was alles duidelijk?

Hoe kunnen we het verbeteren?

Bedankt voor je feedback!

Sectie 4. Hoofdstuk 5
some-alt