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

Kursinnhold

C++ OOP

C++ OOP

1. Grunnleggende om OOP i C++
2. Konstruktører og Destruktører
3. Oversikt Over Innkapsling
4. Oversikt over Arv
5. Oversikt over Polymorfisme

book
Diamantarv

Multippel arv kan føre til en situasjon kjent som diamantproblemet eller diamantarv, som er en betydelig utfordring i objektorienterte programmeringsspråk som støtter multippel arv.

Dette oppstår når en subklasse arver fra to eller flere classes, som selv arver fra en felles superklasse. Begrepet diamant brukes fordi arvestrukturen ligner formen til en diamant.

main.cpp

main.cpp

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

Hovedproblemet med diamantarv er tvetydigheten det skaper. Siden Diamond arver fra både Derived1 og Derived2, som igjen arver fra Base, finnes det to kopier av Base i et objekt av Diamond. Dette kan føre til 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

Nøkkelordet virtual bidrar til å unngå dette problemet. Du kan løse denne uklarheten gjennom virtuell arv ved å bruke nøkkelordet virtual. Når Diamond arver virtuelt, sørger C++ for at kun én kopi av superklassen er til stede, selv om den arves flere ganger gjennom ulike 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
Merk

Prøv å løse tvetydighetsproblemet i det forrige eksempelet ved å benytte virtuell arv.

Implementering av diamantarv

For å implementere diamantarv effektivt, bruk virtual-nøkkelordet i superklassen i de mellomliggende classes. Sørg for konsistent bruk av virtuell arv i alle veier i arvshierarkiet, og vær oppmerksom på rekkefølgen for kall av konstruktører og destruktører.

Løsning av tvetydigheter

En av utfordringene med multippel arv er også å håndtere potensielle tvetydigheter når det gjelder medlemmer med samme navn.

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 superklassene har medlemmer med samme navn, kan subklassen være usikker på hvilken som skal brukes. For å løse slike tvetydigheter, kan du bruke scope resolution operatoren (::) for å spesifisere hvilket medlem fra hvilken baseklasse du ønsker å få tilgang til. 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

Hva er hovedproblemet forårsaket av diamantarv?

Select the correct answer

Alt var klart?

Hvordan kan vi forbedre det?

Takk for tilbakemeldingene dine!

Seksjon 4. Kapittel 5

Spør AI

expand

Spør AI

ChatGPT

Spør om hva du vil, eller prøv ett av de foreslåtte spørsmålene for å starte chatten vår

course content

Kursinnhold

C++ OOP

C++ OOP

1. Grunnleggende om OOP i C++
2. Konstruktører og Destruktører
3. Oversikt Over Innkapsling
4. Oversikt over Arv
5. Oversikt over Polymorfisme

book
Diamantarv

Multippel arv kan føre til en situasjon kjent som diamantproblemet eller diamantarv, som er en betydelig utfordring i objektorienterte programmeringsspråk som støtter multippel arv.

Dette oppstår når en subklasse arver fra to eller flere classes, som selv arver fra en felles superklasse. Begrepet diamant brukes fordi arvestrukturen ligner formen til en diamant.

main.cpp

main.cpp

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

Hovedproblemet med diamantarv er tvetydigheten det skaper. Siden Diamond arver fra både Derived1 og Derived2, som igjen arver fra Base, finnes det to kopier av Base i et objekt av Diamond. Dette kan føre til 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

Nøkkelordet virtual bidrar til å unngå dette problemet. Du kan løse denne uklarheten gjennom virtuell arv ved å bruke nøkkelordet virtual. Når Diamond arver virtuelt, sørger C++ for at kun én kopi av superklassen er til stede, selv om den arves flere ganger gjennom ulike 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
Merk

Prøv å løse tvetydighetsproblemet i det forrige eksempelet ved å benytte virtuell arv.

Implementering av diamantarv

For å implementere diamantarv effektivt, bruk virtual-nøkkelordet i superklassen i de mellomliggende classes. Sørg for konsistent bruk av virtuell arv i alle veier i arvshierarkiet, og vær oppmerksom på rekkefølgen for kall av konstruktører og destruktører.

Løsning av tvetydigheter

En av utfordringene med multippel arv er også å håndtere potensielle tvetydigheter når det gjelder medlemmer med samme navn.

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 superklassene har medlemmer med samme navn, kan subklassen være usikker på hvilken som skal brukes. For å løse slike tvetydigheter, kan du bruke scope resolution operatoren (::) for å spesifisere hvilket medlem fra hvilken baseklasse du ønsker å få tilgang til. 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

Hva er hovedproblemet forårsaket av diamantarv?

Select the correct answer

Alt var klart?

Hvordan kan vi forbedre det?

Takk for tilbakemeldingene dine!

Seksjon 4. Kapittel 5
some-alt