Evnen til en klasse at udlede egenskaber og karakteristika fra en anden klasse kaldes Arv . Arv er en af de vigtigste egenskaber ved objektorienteret programmering.
Arv er en funktion eller en proces, hvor der oprettes nye klasser fra de eksisterende klasser. Den nye klasse, der oprettes, kaldes afledt klasse eller underklasse, og den eksisterende klasse er kendt som basisklassen eller overordnet klasse. Den afledte klasse siges nu at være nedarvet fra basisklassen.
Når vi siger, at afledt klasse arver basisklassen, betyder det, at den afledte klasse arver alle basisklassens egenskaber uden at ændre grundklassens egenskaber og kan tilføje nye funktioner til sine egne. Disse nye funktioner i den afledte klasse vil ikke påvirke basisklassen. Den afledte klasse er den specialiserede klasse for basisklassen.
- Underklasse: Klassen, der arver egenskaber fra en anden klasse, kaldes Subclass eller Derived Class.
- Super klasse: Klassen, hvis egenskaber er nedarvet af en underklasse, kaldes Base Class eller Superclass.
Artiklen er opdelt i følgende underemner:
- Hvorfor og hvornår skal man bruge arv?
- Arvemåder
- Arvetyper
Hvorfor og hvornår skal man bruge arv?
Overvej en gruppe af køretøjer. Du skal oprette klasser for bus, bil og lastbil. Metoderne fuelAmount(), kapacitet(), applyBrakes() vil være de samme for alle tre klasser. Hvis vi opretter disse klasser for at undgå arv, skal vi skrive alle disse funktioner i hver af de tre klasser som vist nedenfor:

javascript søvn
Du kan tydeligt se, at ovenstående proces resulterer i duplikering af den samme kode 3 gange. Dette øger chancerne for fejl og dataredundans. For at undgå denne type situationer bruges arv. Hvis vi opretter en klasse Køretøj og skriver disse tre funktioner i den og arver resten af klasserne fra køretøjsklassen, så kan vi simpelthen undgå duplikering af data og øge genanvendeligheden. Se på nedenstående diagram, hvor de tre klasser er nedarvet fra køretøjsklassen:

Ved hjælp af arv skal vi kun skrive funktionerne én gang i stedet for tre gange, da vi har arvet resten af de tre klasser fra basisklassen (Køretøj).
Implementering af arv i C++ : For at skabe en underklasse, der er nedarvet fra basisklassen, skal vi følge nedenstående syntaks.
Afledte klasser: En afledt klasse er defineret som den klasse, der er afledt af basisklassen.
Syntaks :
class : { //body }>Hvor
klasse — nøgleord for at oprette en ny klasse
derived_class_name — navnet på den nye klasse, som vil arve basisklassen
adgangsspecifikation - enten af privat, offentlig eller beskyttet. Hvis ingen af dem er angivet, tages PRIVAT som standard
base-class-name — navnet på basisklassen
Bemærk : En afledt klasse arver ikke adgang til private datamedlemmer. Det arver dog et fuldt overordnet objekt, som indeholder alle private medlemmer, som den klasse erklærer.
Eksempel:
1. klasse ABC : privat XYZ //privat afledning
{ }
2. klasse ABC : offentlig XYZ //offentlig afledning
{ }
3. klasse ABC : beskyttet XYZ //beskyttet afledning
{ }
4. klasse ABC: XYZ //privat afledning som standard
{ }
Bemærk:
o Når en basisklasse er privat nedarvet af den afledte klasse, bliver offentlige medlemmer af basisklassen de private medlemmer af den afledte klasse, og derfor kan de offentlige medlemmer af basisklassen kun tilgås af medlemsfunktionerne i den afledte klasse. De er utilgængelige for objekterne i den afledte klasse.
o På den anden side, når basisklassen er offentligt nedarvet af den afledte klasse, bliver offentlige medlemmer af basisklassen også de offentlige medlemmer af den afledte klasse. Derfor er de offentlige medlemmer af basisklassen tilgængelige for objekterne i den afledte klasse såvel som af medlemsfunktionerne i den afledte klasse.
// Example: define member function without argument within // the class #include using namespace std; class Person { int id; char name[100]; public: void set_p() { cout << 'Enter the Id:'; cin>> id; cout<< 'Enter the Name:'; cin>> navn; } void display_p() { cout<< endl <<'Id: '<< id << '
Name: ' << name <> kursus; cout<< 'Enter the Course Fee:'; cin>> gebyr; } void display_s() { display_p(); cout<<'Course: '<< course << '
Fee: ' << fee << endl; } }; int main() { Student s; s.set_s(); s.display_s(); return 0; }> Produktion:
computernetværk
Enter the Id: 101 Enter the Name: Dev Enter the Course Name: GCS Enter the Course Fee:70000 Id: 101 Name: Dev Course: GCS Fee: 70000>C++
// Example: define member function without argument outside the class #include using namespace std; class Person { int id; char name[100]; public: void set_p(); void display_p(); }; void Person::set_p() { cout<<'Enter the Id:'; cin>>id; cout<<'Enter the Name:'; cin>> navn; } void Person::display_p() { cout<> selvfølgelig; cout<<'Enter the Course Fee:'; cin>> gebyr; } void Student::display_s() { display_p(); cout<<'
Course: '< Produktion:
Enter the Id: 101 Enter the Name: Dev Enter the Course Name: GCS Enter the Course Fee: 70000 Id: 101 Name: Dev Course: GCS Fee: 70000>C++
// Example: define member function with argument outside the class #include #include using namespace std; class Person { int id; char name[100]; public: void set_p(int,char[]); void display_p(); }; void Person::set_p(int id,char n[]) { this->id=id; strcpy(dette->navn,n); } void Person::display_p() { cout< CPP
// C++ program to demonstrate implementation // of Inheritance #include using namespace std; // Base class class Parent { public: int id_p; }; // Sub class inheriting from Base Class(Parent) class Child : public Parent { public: int id_c; }; // main function int main() { Child obj1; // An object of class child has all data members // and member functions of class parent obj1.id_c = 7; obj1.id_p = 91; cout << 'Child id is: ' << obj1.id_c << '
'; cout << 'Parent id is: ' << obj1.id_p << '
'; return 0; }> Produktion
Child id is: 7 Parent id is: 91>
I ovenstående program er 'Barn'-klassen offentligt nedarvet fra 'Forældre'-klassen, så de offentlige datamedlemmer af klassen 'Forældre' vil også blive nedarvet af klassen 'Barn'.
Arvemåder: Der er 3 former for arv.
- Offentlig tilstand : Hvis vi udleder en underklasse fra en offentlig basisklasse. Så vil det offentlige medlem af basisklassen blive offentligt i den afledte klasse, og beskyttede medlemmer af basisklassen vil blive beskyttet i den afledte klasse.
- Beskyttet tilstand : Hvis vi udleder en underklasse fra en beskyttet basisklasse. Så vil både offentlige medlemmer og beskyttede medlemmer af basisklassen blive beskyttet i den afledte klasse.
- Privat tilstand : Hvis vi udleder en underklasse fra en Privat basisklasse. Så bliver både offentlige medlemmer og beskyttede medlemmer af basisklassen Private i den afledte klasse.
Bemærk: De private medlemmer i basisklassen kan ikke tilgås direkte i den afledte klasse, mens beskyttede medlemmer kan tilgås direkte. For eksempel indeholder klasserne B, C og D alle variablerne x, y og z i eksemplet nedenfor. Det er kun et spørgsmål om adgang.
CPP // C++ Implementation to show that a derived class // doesn’t inherit access to private data members. // However, it does inherit a full parent object. class A { public: int x; protected: int y; private: int z; }; class B : public A { // x is public // y is protected // z is not accessible from B }; class C : protected A { // x is protected // y is protected // z is not accessible from C }; class D : private A // 'private' is default for classes { // x is private // y is private // z is not accessible from D };>
Nedenstående tabel opsummerer ovenstående tre tilstande og viser adgangsspecifikationen for medlemmerne af basisklassen i underklassen, når de er afledt i offentlige, beskyttede og private tilstande:

Arvetyper: -
- Enkeltarv
- Multilevel arv
- Multipel arv
- Hierarkisk arv
- Hybrid arv
Typer af arv i C++
1. Enearv : I enkeltarv må en klasse kun arve fra én klasse. dvs. én underklasse nedarves kun af én basisklasse.

Syntaks :
class subclass_name : access_mode base_class { // body of subclass }; OR class A { ... .. ... }; class B: public A { ... .. ... };>CPP // C++ program to explain // Single inheritance #include using namespace std; // base class class Vehicle { public: Vehicle() { cout << 'This is a Vehicle
'; } }; // sub class derived from a single base classes class Car : public Vehicle { }; // main function int main() { // Creating object of sub class will // invoke the constructor of base classes Car obj; return 0; }> Produktion
This is a Vehicle>
C++
// Example: #include using namespace std; class A { protected: int a; public: void set_A() { cout<<'Enter the Value of A='; cin>>a; } void disp_A() { cout< Output:- Indtast værdien af A= 3 3 Indtast værdien af B= 5 5 Produkt af 3 * 5 = 15
C++
// Example: #include using namespace std; class A { protected: int a; public: void set_A(int x) { a=x; } void disp_A() { cout< Produktion
Product of 4 * 5 = 20>
2. Multipel arv: Multiple Inheritance er en funktion i C++, hvor en klasse kan arve fra mere end én klasse. dvs en underklasse er arvet fra mere end én basisklasse .

Syntaks :
class subclass_name : access_mode base_class1, access_mode base_class2, .... { // body of subclass }; class B { ... .. ... }; class C { ... .. ... }; class A: public B, public C { ... ... ... };>Her vil antallet af basisklasser blive adskilt af et komma (', '), og adgangstilstanden for hver basisklasse skal angives.
CPP // C++ program to explain // multiple inheritance #include using namespace std; // first base class class Vehicle { public: Vehicle() { cout << 'This is a Vehicle
'; } }; // second base class class FourWheeler { public: FourWheeler() { cout << 'This is a 4 wheeler Vehicle
'; } }; // sub class derived from two base classes class Car : public Vehicle, public FourWheeler { }; // main function int main() { // Creating object of sub class will // invoke the constructor of base classes. Car obj; return 0; }> Produktion
This is a Vehicle This is a 4 wheeler Vehicle>
C++
// Example: #include using namespace std; class A { protected: int a; public: void set_A() { cout<<'Enter the Value of A='; cin>>a; } void disp_A() { cout<
For at vide mere om det, se venligst artiklen Flere arv .
3. Multilevel Arv : I denne type arv oprettes en afledt klasse fra en anden afledt klasse.

ikke-deterministiske endelige automater
Syntaks:-
class C { ... .. ... }; class B:public C { ... .. ... }; class A: public B { ... ... ... };>CPP // C++ program to implement // Multilevel Inheritance #include using namespace std; // base class class Vehicle { public: Vehicle() { cout << 'This is a Vehicle
'; } }; // first sub_class derived from class vehicle class fourWheeler : public Vehicle { public: fourWheeler() { cout << 'Objects with 4 wheels are vehicles
'; } }; // sub class derived from the derived base class fourWheeler class Car : public fourWheeler { public: Car() { cout << 'Car has 4 Wheels
'; } }; // main function int main() { // Creating object of sub class will // invoke the constructor of base classes. Car obj; return 0; }> Produktion
This is a Vehicle Objects with 4 wheels are vehicles Car has 4 Wheels>
4. Hierarkisk arv : I denne type arv nedarves mere end én underklasse fra en enkelt basisklasse. dvs. mere end én afledt klasse er oprettet fra en enkelt basisklasse.

Syntaks:-
class A { // body of the class A. } class B : public A { // body of class B. } class C : public A { // body of class C. } class D : public A { // body of class D. }>CPP // C++ program to implement // Hierarchical Inheritance #include using namespace std; // base class class Vehicle { public: Vehicle() { cout << 'This is a Vehicle
'; } }; // first sub class class Car : public Vehicle { }; // second sub class class Bus : public Vehicle { }; // main function int main() { // Creating object of sub class will // invoke the constructor of base class. Car obj1; Bus obj2; return 0; }> Produktion
This is a Vehicle This is a Vehicle>
5. Hybrid (virtuel) arv : Hybrid arv implementeres ved at kombinere mere end én type arv. For eksempel: Kombination af hierarkisk arv og multipel arv.
Nedenstående billede viser kombinationen af hierarkisk og multiple arv:

// C++ program for Hybrid Inheritance #include using namespace std; // base class class Vehicle { public: Vehicle() { cout << 'This is a Vehicle
'; } }; // base class class Fare { public: Fare() { cout << 'Fare of Vehicle
'; } }; // first sub class class Car : public Vehicle { }; // second sub class class Bus : public Vehicle, public Fare { }; // main function int main() { // Creating object of sub class will // invoke the constructor of base class. Bus obj2; return 0; }> Produktion
This is a Vehicle Fare of Vehicle>C++
// Example: #include using namespace std; class A { protected: int a; public: void get_a() { cout << 'Enter the value of 'a' : '; cin>>a; } }; klasse B : offentlig A { beskyttet: int b; offentlig: void get_b() { cout<< 'Enter the value of 'b' : '; cin>>b; } }; klasse C { beskyttet: int c; public: void get_c() { cout<< 'Enter the value of c is : '; cin>>c; } }; klasse D : offentlig B, offentlig C { beskyttet: int d; public: void mul() { get_a(); få_b(); get_c(); cout<< 'Multiplication of a,b,c is : ' <
6. Et særligt tilfælde af hybrid arv: Multipath arv :
En afledt klasse med to basisklasser, og disse to basisklasser har én fælles basisklasse, kaldes flervejsarv. Tvetydighed kan opstå i denne type arv.
Eksempel:
// C++ program demonstrating ambiguity in Multipath // Inheritance #include using namespace std; class ClassA { public: int a; }; class ClassB : public ClassA { public: int b; }; class ClassC : public ClassA { public: int c; }; class ClassD : public ClassB, public ClassC { public: int d; }; int main() { ClassD obj; // obj.a = 10; // Statement 1, Error // obj.a = 100; // Statement 2, Error obj.ClassB::a = 10; // Statement 3 obj.ClassC::a = 100; // Statement 4 obj.b = 20; obj.c = 30; obj.d = 40; cout << ' a from ClassB : ' << obj.ClassB::a; cout << '
a from ClassC : ' << obj.ClassC::a; cout << '
b : ' << obj.b; cout << '
c : ' << obj.c; cout << '
d : ' << obj.d << '
'; }> Produktion
a from ClassB : 10 a from ClassC : 100 b : 20 c : 30 d : 40>
I ovenstående eksempel arver både ClassB og ClassC ClassA, de har begge en enkelt kopi af ClassA. Klasse-D arver dog både ClassB og ClassC, derfor har Class-D to kopier af ClassA, en fra ClassB og en anden fra ClassC.
Hvis vi har brug for at få adgang til datamedlemmet af ClassA gennem objektet i Klasse-D, skal vi specificere stien, hvorfra a vil blive tilgået, uanset om det er fra ClassB eller ClassC, bcoz compiler kan ikke skelne mellem to kopier af ClassA i Klasse-D.
Der er 2 måder at undgå denne tvetydighed på:
1) Undgå tvetydighed ved brug af scope resolution operator: Ved at bruge scope resolution-operatoren kan vi manuelt specificere stien, hvorfra datamedlem a vil blive tilgået, som vist i sætning 3 og 4 i ovenstående eksempel.
CPP obj.ClassB::a = 10; // Statement 3 obj.ClassC::a = 100; // Statement 4>
Bemærk: Alligevel er der to kopier af ClassA i klasse-D.
2) Undgå tvetydighed ved hjælp af den virtuelle basisklasse:
prøve javascriptCPP
#include class ClassA { public: int a; }; class ClassB : virtual public ClassA { public: int b; }; class ClassC : virtual public ClassA { public: int c; }; class ClassD : public ClassB, public ClassC { public: int d; }; int main() { ClassD obj; obj.a = 10; // Statement 3 obj.a = 100; // Statement 4 obj.b = 20; obj.c = 30; obj.d = 40; cout << '
a : ' << obj.a; cout << '
b : ' << obj.b; cout << '
c : ' << obj.c; cout << '
d : ' << obj.d << '
'; }> Produktion:
a : 100 b : 20 c : 30 d : 40>
Ifølge ovenstående eksempel har Klasse-D kun én kopi af KlasseA, derfor vil sætning 4 overskrive værdien af a, givet i sætning 3.