Nedarvning i C++
Arv er et grundlæggende begreb i OOP (objektorienteret programmering) . Det er den mekanisme, hvorved en klasse får lov til at arve funktionerne (felter og metoder) fra en anden klasse. Arv betyder at skabe nye klasser baseret på eksisterende. En klasse, der arver fra en anden klasse, kan genbruge den pågældende klasses metoder og felter.
Eksempel: I det følgende eksempel er dyr basisklassen, og hund kat og ko er afledte klasser, der udvider dyreklassen.
Inheritance C++ #include using namespace std ; class Animal { public : void sound () { cout < < 'Animal makes a sound' < < endl ; } }; class Dog : public Animal { public : void sound () { cout < < 'Dog barks' < < endl ; } }; class Cat : public Animal { public : void sound () { cout < < 'Cat meows' < < endl ; } }; class Cow : public Animal { public : void sound () { cout < < 'Cow moos' < < endl ; } }; int main () { Dog d ; d . sound (); Cat c ; c . sound (); Cow cow ; cow . sound (); return 0 ; }
Produktion
Dog barks Cat meows Cow moos
Forklaring:
- Animal er basisklassen med en funktion sound().
- Dog Cat og Cow er afledte klasser, der hver definerer deres egen sound() metode.
- I main() oprettes objekter af Dog Cat og Cow separat.
- Når vi kalder sound() på hvert objekt, kører den respektive underordnede klassemetode (Hund gøer Kat mjaver Cow moos).
Syntaks
C++ class ChildClass : public ParentClass { // Additional fields and methods };
Hvordan fungerer arv i C++?
Tyktarmen (:) med en adgangsspecifikation bruges til nedarvning i C++. Det giver den afledte klasse (underordnet klasse) mulighed for at arve datamedlemmerne (felter) og medlemsfunktioner (metoder) af basisklassen (overordnet klasse).
Når en klasse arver en anden klasse, får den alle de tilgængelige medlemmer af den overordnede klasse, og den underordnede klasse kan også omdefinere (tilsidesætte) eller tilføje ny funktionalitet til dem.
Typer af arv i C++
Nedenfor er de forskellige typer af arv, som understøttes af C++.
1. Enearv
I enkeltarv er en underklasse kun afledt af én superklasse. Det arver egenskaberne og adfærden fra en enkeltforælderklasse. Nogle gange er det også kendt som simpel arv.
Single Inheritance C++ #include using namespace std ; class Vehicle { public : Vehicle () { cout < < 'This is a Vehicle' < < endl ; } }; class Car : public Vehicle { public : Car () { cout < < 'This Vehicle is Car' < < endl ; } }; int main () { Car obj ; return 0 ; }
Produktion
This is a Vehicle This Vehicle is Car
2. Multipel arv
I Multipel arv én klasse kan have mere end én superklasse og arve funktioner fra alle overordnede klasser.
Multiple Inheritance C++ #include using namespace std ; class LandVehicle { public : void landInfo () { cout < < 'This is a LandVehicle' < < endl ; } }; class WaterVehicle { public : void waterInfo () { cout < < 'This is a WaterVehicle' < < endl ; } }; // Derived class inheriting from both base classes class AmphibiousVehicle : public LandVehicle public WaterVehicle { public : AmphibiousVehicle () { cout < < 'This is an AmphibiousVehicle' < < endl ; } }; int main () { AmphibiousVehicle obj ; obj . waterInfo (); obj . landInfo (); return 0 ; }
Produktion
This is an AmphibiousVehicle This is a WaterVehicle This is a LandVehicle
3. Multilevel Arv
Multilevel arv i C++ betyder, at en klasse er afledt af en anden afledt klasse, der danner en arvekæde.
Multilevel Inheritance C++ #include using namespace std ; class Vehicle { public : Vehicle () { cout < < 'This is a Vehicle' < < endl ; } }; // Derived class from Vehicle class FourWheeler : public Vehicle { public : FourWheeler () { cout < < '4 Wheeler Vehicles' < < endl ; } }; // Derived class from FourWheeler class Car : public FourWheeler { public : Car () { cout < < 'This 4 Wheeler Vehicle is a Car' < < endl ; } }; int main () { Car obj ; return 0 ; }
Produktion
This is a Vehicle 4 Wheeler Vehicles This 4 Wheeler Vehicle is a Car
4. Hierarkisk arv
I hierarkisk nedarvning nedarves mere end én underklasse fra en enkelt basisklasse. dvs. mere end én afledt klasse er oprettet fra en enkelt basisklasse. For eksempel er både biler og busser køretøjer.
Hierarchical Inheritance C++ #include using namespace std ; class Vehicle { public : Vehicle () { cout < < 'This is a Vehicle' < < endl ; } }; class Car : public Vehicle { public : Car () { cout < < 'This Vehicle is Car' < < endl ; } }; class Bus : public Vehicle { public : Bus () { cout < < 'This Vehicle is Bus' < < endl ; } }; int main () { Car obj1 ; Bus obj2 ; return 0 ; }
Produktion
This is a Vehicle This Vehicle is Car This is a Vehicle This Vehicle is Bus
5. Hybrid arv
Når to eller flere typer arv kombineres i et program. For eksempel kan en klasse bruge multipel nedarvning og også være en del af en multilevel nedarvningskæde.
Hybrid Inheritance C++ #include using namespace std ; class Vehicle { public : Vehicle () { cout < < 'This is a Vehicle' < < endl ; } }; class Fare { public : Fare () { cout < < 'Fare of Vehicle' < < endl ; } }; class Car : public Vehicle { public : Car () { cout < < 'This Vehical is a Car' < < endl ; } }; class Bus : public Vehicle public Fare { public : Bus () { cout < < 'This Vehicle is a Bus with Fare' ; } }; int main () { Bus obj2 ; return 0 ; }
Produktion
This is a Vehicle Fare of Vehicle This Vehicle is a Bus with Fare
Hybrid arv kan føre til diamant problem i C++. Dette sker, når en klasse arver fra to klasser, der begge deler den samme basisklasse. Som et resultat får den afledte klasse flere kopier af basisklassemedlemmerne, hvilket skaber uklarhed om, hvilken der skal bruges.
Bemærk: Løsningen er at bruge virtuel arv, så kun en enkelt kopi af basisklassen deles.
Fordele ved arv i C++
- Kode Genanvendelighed : Afledt klasse kan direkte genbruge datamedlemmer og metoder i dens basisklasse og undgå kodeduplikering.
- Abstraktion: Understøtter abstrakte klasser (klasser med rene virtuelle funktioner), der definerer en fælles grænseflade, der håndhæver abstraktion.
- Klassehierarki: Du kan bygge hierarkier (grundlag → afledt → yderligere afledt) for at modellere relationer i den virkelige verden.
- Polymorfi: Understøtter fuldt ud runtime-polymorfi gennem virtuelle funktioner og også kompilerings-tidspolymorfi via funktionsoverbelastning og skabeloner.
Ulemper ved arv i C++
- Tæt kobling: Barneklassen bliver afhængig af forældreklassen. Enhver ændring i basisklassen kan fremtvinge ændringer i afledte klasser.
- Reduceret fleksibilitet: Nogle gange misbruges arv, hvor sammensætning (har-et forhold) bedre ville føre til mindre fleksibel kode.
- Øget kompleksitet: Dybe nedarvningshierarkier (flere niveauer eller hybrider) kan gøre koden svær at forstå, vedligeholde og fejlfinde.
- Diamantproblem: Med hybrid eller multipel nedarvning kan der opstå tvetydighed, hvis den samme basisklasse nedarves flere gange.
- Overhead af virtuelle funktioner: Hvis polymorfi (virtuelle funktioner) bruges, er der en lille driftstid på grund af virtuelle tabelopslag.