Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lära Diamantärvning | Översikt av Arv
C++ OOP
course content

Kursinnehåll

C++ OOP

C++ OOP

1. Grunderna i OOP i C++
2. Konstruktorer och Destruktorer
3. Översikt Av Inkapsling
4. Översikt av Arv
5. Översikt av Polymorfism

book
Diamantärvning

Multipelt arv kan leda till en situation som kallas diamantproblemet eller diamantarv, vilket är en betydande utmaning i objektorienterade programmeringsspråk som stöder multipelt arv.

Detta uppstår när en subklass ärver från två eller flera classes, som själva ärver från en gemensam superklass. Termen diamant används eftersom arvstrukturen liknar formen av en diamant.

main.cpp

main.cpp

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

Det huvudsakliga problemet med diamantarv är den tvetydighet som uppstår. Eftersom Diamond ärver från både Derived1 och Derived2, vilka i sin tur ärver från Base, finns det två kopior av Base inom ett objekt av typen Diamond. Detta kan leda till tvetydighet.

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

Lösning på problemet

Nyckelordet virtual hjälper till att undvika detta problem. Du kan lösa denna tvetydighet genom virtuell arv genom att använda nyckelordet virtual. När Diamond ärver virtuellt säkerställer C++ att endast en kopia av superklassen finns, även om den ärvs flera gånger genom olika vägar.

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
Notering

Försök att lösa tvetydighetsproblemet i det föregående exemplet genom att använda virtuell arv.

Implementering av diamantarv

För att implementera diamantarv effektivt, använd virtual-nyckelordet i superklassens deklaration inom de intermediära classes. Säkerställ konsekvent användning av virtuellt arv i alla vägar i arvshierarkin och var uppmärksam på ordningen för anrop av konstruktorer och destruktorer.

Lösning av tvetydigheter

En av utmaningarna med multipelt arv är även att hantera potentiella tvetydigheter när det gäller medlemmar med samma namn.

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

Om båda superklasserna har medlemmar med samma namn kan subklassen vara osäker på vilken som ska användas. För att lösa sådana tvetydigheter kan du använda scope resolution operatorn (::) för att specificera vilken basklassmedlem du vill komma åt. Till exempel:

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

Vad är det främsta problemet som orsakas av diamantärvning?

Select the correct answer

Var allt tydligt?

Hur kan vi förbättra det?

Tack för dina kommentarer!

Avsnitt 4. Kapitel 5

Fråga AI

expand

Fråga AI

ChatGPT

Fråga vad du vill eller prova någon av de föreslagna frågorna för att starta vårt samtal

course content

Kursinnehåll

C++ OOP

C++ OOP

1. Grunderna i OOP i C++
2. Konstruktorer och Destruktorer
3. Översikt Av Inkapsling
4. Översikt av Arv
5. Översikt av Polymorfism

book
Diamantärvning

Multipelt arv kan leda till en situation som kallas diamantproblemet eller diamantarv, vilket är en betydande utmaning i objektorienterade programmeringsspråk som stöder multipelt arv.

Detta uppstår när en subklass ärver från två eller flera classes, som själva ärver från en gemensam superklass. Termen diamant används eftersom arvstrukturen liknar formen av en diamant.

main.cpp

main.cpp

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

Det huvudsakliga problemet med diamantarv är den tvetydighet som uppstår. Eftersom Diamond ärver från både Derived1 och Derived2, vilka i sin tur ärver från Base, finns det två kopior av Base inom ett objekt av typen Diamond. Detta kan leda till tvetydighet.

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

Lösning på problemet

Nyckelordet virtual hjälper till att undvika detta problem. Du kan lösa denna tvetydighet genom virtuell arv genom att använda nyckelordet virtual. När Diamond ärver virtuellt säkerställer C++ att endast en kopia av superklassen finns, även om den ärvs flera gånger genom olika vägar.

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
Notering

Försök att lösa tvetydighetsproblemet i det föregående exemplet genom att använda virtuell arv.

Implementering av diamantarv

För att implementera diamantarv effektivt, använd virtual-nyckelordet i superklassens deklaration inom de intermediära classes. Säkerställ konsekvent användning av virtuellt arv i alla vägar i arvshierarkin och var uppmärksam på ordningen för anrop av konstruktorer och destruktorer.

Lösning av tvetydigheter

En av utmaningarna med multipelt arv är även att hantera potentiella tvetydigheter när det gäller medlemmar med samma namn.

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

Om båda superklasserna har medlemmar med samma namn kan subklassen vara osäker på vilken som ska användas. För att lösa sådana tvetydigheter kan du använda scope resolution operatorn (::) för att specificera vilken basklassmedlem du vill komma åt. Till exempel:

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

Vad är det främsta problemet som orsakas av diamantärvning?

Select the correct answer

Var allt tydligt?

Hur kan vi förbättra det?

Tack för dina kommentarer!

Avsnitt 4. Kapitel 5
some-alt