Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lære Diamantarv | Oversigt over Arv
C++ OOP
course content

Kursusindhold

C++ OOP

C++ OOP

1. Grundlæggende OOP i C++
2. Konstruktører og Destruktører
3. Oversigt Over Indkapsling
4. Oversigt over Arv
5. Oversigt Over Polymorfi

book
Diamantarv

Multipel arv kan føre til en situation kendt som diamantproblemet eller diamantarv, hvilket er en væsentlig udfordring i objektorienterede programmeringssprog, der understøtter multipel arv.

Dette opstår, når en subklasse arver fra to eller flere classes, som selv arver fra en fælles superklasse. Udtrykket diamant bruges, fordi arvestrukturen ligner formen af 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 primære problem med diamantarv er den tvetydighed, det skaber. Da Diamond arver fra både Derived1 og Derived2, som hver især arver fra Base, findes der to kopier af Base i et objekt af typen Diamond. Dette kan føre til tvetydighed.

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

Nøgleordet virtual hjælper med at undgå dette problem. Du kan løse denne tvetydighed gennem virtuel arv ved at bruge nøgleordet virtual. Når Diamond arver virtuelt, sikrer C++, at kun én kopi af superklassen er til stede, selvom den arves flere gange gennem forskellige stier.

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
Bemærk

Prøv at løse tvetydighedsproblemet i det forrige eksempel ved at anvende virtuel arv.

Implementering af diamantarv

For at implementere diamantarv effektivt, anvend virtual-nøgleordet i superklassens deklaration inden for de mellemliggende classes. Sørg for konsekvent brug af virtuel arv i alle veje i arvshierarkiet, og vær opmærksom på rækkefølgen af kald til konstruktører og destruktører.

Løsning af tvetydigheder

En af udfordringerne ved multipel arv er også håndtering af potentielle tvetydigheder, når det gælder medlemmer med samme navne.

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

Hvis begge superklasser har medlemmer med samme navn, kan subklassen være usikker på, hvilken der skal bruges. For at løse sådanne tvetydigheder kan du bruge scope resolution operatoren (::) til at specificere, hvilket basisklasses medlem du vil tilgå. For eksempel:

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

Hvad er det primære problem forårsaget af diamant-arv?

Select the correct answer

Var alt klart?

Hvordan kan vi forbedre det?

Tak for dine kommentarer!

Sektion 4. Kapitel 5

Spørg AI

expand

Spørg AI

ChatGPT

Spørg om hvad som helst eller prøv et af de foreslåede spørgsmål for at starte vores chat

course content

Kursusindhold

C++ OOP

C++ OOP

1. Grundlæggende OOP i C++
2. Konstruktører og Destruktører
3. Oversigt Over Indkapsling
4. Oversigt over Arv
5. Oversigt Over Polymorfi

book
Diamantarv

Multipel arv kan føre til en situation kendt som diamantproblemet eller diamantarv, hvilket er en væsentlig udfordring i objektorienterede programmeringssprog, der understøtter multipel arv.

Dette opstår, når en subklasse arver fra to eller flere classes, som selv arver fra en fælles superklasse. Udtrykket diamant bruges, fordi arvestrukturen ligner formen af 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 primære problem med diamantarv er den tvetydighed, det skaber. Da Diamond arver fra både Derived1 og Derived2, som hver især arver fra Base, findes der to kopier af Base i et objekt af typen Diamond. Dette kan føre til tvetydighed.

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

Nøgleordet virtual hjælper med at undgå dette problem. Du kan løse denne tvetydighed gennem virtuel arv ved at bruge nøgleordet virtual. Når Diamond arver virtuelt, sikrer C++, at kun én kopi af superklassen er til stede, selvom den arves flere gange gennem forskellige stier.

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
Bemærk

Prøv at løse tvetydighedsproblemet i det forrige eksempel ved at anvende virtuel arv.

Implementering af diamantarv

For at implementere diamantarv effektivt, anvend virtual-nøgleordet i superklassens deklaration inden for de mellemliggende classes. Sørg for konsekvent brug af virtuel arv i alle veje i arvshierarkiet, og vær opmærksom på rækkefølgen af kald til konstruktører og destruktører.

Løsning af tvetydigheder

En af udfordringerne ved multipel arv er også håndtering af potentielle tvetydigheder, når det gælder medlemmer med samme navne.

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

Hvis begge superklasser har medlemmer med samme navn, kan subklassen være usikker på, hvilken der skal bruges. For at løse sådanne tvetydigheder kan du bruge scope resolution operatoren (::) til at specificere, hvilket basisklasses medlem du vil tilgå. For eksempel:

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

Hvad er det primære problem forårsaget af diamant-arv?

Select the correct answer

Var alt klart?

Hvordan kan vi forbedre det?

Tak for dine kommentarer!

Sektion 4. Kapitel 5
some-alt