Arv i C++

 C Programming >> C C# Program >  >> C++
Arv i C++

Muligheten til en klasse til å utlede egenskaper og egenskaper fra en annen klasse kalles arv . Arv er en av de viktigste egenskapene til objektorientert programmering.

Arv er en funksjon eller en prosess der nye klasser opprettes fra de eksisterende klassene. Den nye klassen som er opprettet kalles "avledet klasse" eller "barneklasse", og den eksisterende klassen er kjent som "grunnklassen" eller "overordnet klasse". Den avledede klassen sies nå å være arvet fra basisklassen.

Når vi sier at avledet klasse arver basisklassen, betyr det at den avledede klassen arver alle egenskapene til basisklassen, uten å endre egenskapene til basisklassen og kan legge til nye funksjoner til sine egne . Disse nye funksjonene i den avledede klassen vil ikke påvirke basisklassen. Den avledede klassen er den spesialiserte klassen for basisklassen.

  • Underklasse: Klassen som arver egenskaper fra en annen klasse kalles Subclass eller Derived Class.
  • Superklasse: Klassen hvis egenskaper er arvet av en underklasse kalles Base Class eller Superclass.

Artikkelen er delt inn i følgende underemner:

  • Hvorfor og når skal man bruke arv?
  • Modi for arv
  • Typer arv

Hvorfor og når skal man bruke arv?

Vurder en gruppe kjøretøy. Du må opprette klasser for buss, bil og lastebil. Metodene fuelAmount(), capacity(), applyBrakes() vil være de samme for alle tre klassene. Hvis vi oppretter disse klassene for å unngå arv, må vi skrive alle disse funksjonene i hver av de tre klassene som vist under figuren:

Du kan tydelig se at prosessen ovenfor resulterer i duplisering av samme kode 3 ganger. Dette øker sjansene for feil og dataredundans. For å unngå denne typen situasjoner brukes arv. Hvis vi oppretter en klasse Vehicle og skriver disse tre funksjonene i den og arver resten av klassene fra kjøretøyklassen, så kan vi ganske enkelt unngå duplisering av data og øke gjenbrukbarheten. Se på diagrammet nedenfor der de tre klassene er arvet fra kjøretøyklassen:

Ved å bruke arv, må vi skrive funksjonene bare én gang i stedet for tre ganger ettersom vi har arvet resten av de tre klassene fra basisklassen (Kjøretøy).
Implementering av arv i C++ :For å lage en underklasse som er arvet fra basisklassen må vi følge syntaksen nedenfor.

Avledede klasser: En avledet klasse er definert som klassen avledet fra basisklassen.
Syntaks :

class  <derived_class_name> : <access-specifier> <base_class_name>
{
        //body
}

Hvor
klasse — nøkkelord for å opprette en ny klasse
derived_class_name — navnet på den nye klassen, som vil arve basisklassen
tilgangsspesifikasjoner - enten privat, offentlig eller beskyttet. Hvis ingen av disse er spesifisert, tas PRIVAT som standard
base-class-name — navnet på basisklassen
Merk :En avledet klasse arver ikke tilgang til private datamedlemmer. Den arver imidlertid et fullstendig overordnet objekt, som inneholder eventuelle private medlemmer som den klassen erklærer.

Eksempel:
1. klasse ABC :privat XYZ //privat avledning
{ }
2. klasse ABC :offentlig XYZ //offentlig avledning
{ }
3. klasse ABC :beskyttet XYZ //beskyttet avledning
{ }
4. klasse ABC:XYZ //privat avledning som standard
{ }

Merk:

o Når en basisklasse arves privat av den avledede klassen, blir offentlige medlemmer av basisklassen de private medlemmene av den avledede klassen, og derfor kan de offentlige medlemmene av basisklassen bare nås av medlemsfunksjonene til den avledede klassen. De er utilgjengelige for objektene til den avledede klassen.
o På den annen side, når basisklassen er offentlig arvet av den avledede klassen, blir offentlige medlemmer av basisklassen også offentlige medlemmer av den avledede klassen. Derfor er de offentlige medlemmene av basisklassen tilgjengelige for objektene til den avledede klassen så vel som av medlemsfunksjonene til den avledede klassen.




// Example: define member function without argument within the class #include<iostream> using namespace std; class Person {      int id;      char name[100];         public :          void set_p()          {              cout<< "Enter the Id:" ;              cin>>id;              fflush (stdin);              cout<< "Enter the Name:" ;              cin.get(name,100);          }             void display_p()          {              cout<<endl<<id<< "\t" <<name;          } }; class Student: private Person {      char course[50];      int fee;           public :      void set_s()          {              set_p();              cout<< "Enter the Course Name:" ;              fflush (stdin);              cin.getline(course,50);              cout<< "Enter the Course Fee:" ;              cin>>fee;          }                   void display_s()          {              display_p();              cout<< "t" <<course<< "\t" <<fee;          } }; main() {      Student s;      s.set_s();      s.display_s();      return 0; }

 

 

Utdata

Enter the Id:Enter the Name:Enter the Course Name:Enter the Course Fee:
0    t    0




// Example: define member function without argument outside the class #include<iostream> 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;      fflush (stdin);      cout<< "Enter the Name:" ;      cin.get(name,100); } void Person::display_p() {      cout<<endl<<id<< "\t" <<name; } class Student: private Person {      char course[50];      int fee;           public :          void set_s();          void display_s(); }; void Student::set_s() {      set_p();      cout<< "Enter the Course Name:" ;      fflush (stdin);      cin.getline(course,50);      cout<< "Enter the Course Fee:" ;      cin>>fee; } void Student::display_s() {      display_p();      cout<< "t" <<course<< "\t" <<fee; } main() {      Student s;      s.set_s();      s.display_s();      return 0; }

 

 

Utdata

Enter the Id:Enter the Name:Enter the Course Name:Enter the Course Fee:
0    t    0




// Example: define member function with argument outside the class #include<iostream> #include<string.h> 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 ( this ->name,n);        } void Person::display_p() {      cout<<endl<<id<< "\t" <<name; } class Student: private Person {      char course[50];      int fee;      public :      void set_s( int , char [], char [], int );      void display_s(); }; void Student::set_s( int id, char n[], char c[], int f) {      set_p(id,n);      strcpy (course,c);      fee=f; } void Student::display_s() {      display_p();      cout<< "t" <<course<< "\t" <<fee; } main() {      Student s;      s.set_s(1001, "Ram" , "B.Tech" ,2000);      s.display_s();      return 0; }

 

 




// C++ program to demonstrate implementation // of Inheritance #include <bits/stdc++.h> 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 << '\n' ;      cout << "Parent id is: " << obj1.id_p << '\n' ;      return 0; }

 

 

Utdata

Child id is: 7
Parent id is: 91

Utdata:

Child id is: 7
Parent id is: 91

I programmet ovenfor er 'Child'-klassen offentlig arvet fra 'Prent'-klassen, så de offentlige datamedlemmene i klassen 'Prent' vil også bli arvet av klassen 'Child' .
Modi for arv: Det er 3 moduser for arv.

  1. Offentlig modus :Hvis vi utleder en underklasse fra en offentlig basisklasse. Da vil det offentlige medlemmet av basisklassen bli offentlig i den avledede klassen og beskyttede medlemmer av basisklassen vil bli beskyttet i den avledede klassen.
  2. Beskyttet modus :Hvis vi utleder en underklasse fra en beskyttet basisklasse. Da vil både offentlige medlemmer og beskyttede medlemmer av basisklassen bli beskyttet i den avledede klassen.
  3. Privat modus :Hvis vi utleder en underklasse fra en privat basisklasse. Da vil både offentlige medlemmer og beskyttede medlemmer av basisklassen bli Private i den avledede klassen.

Merk: De private medlemmene i basisklassen kan ikke fås direkte i den avledede klassen, mens beskyttede medlemmer kan fås direkte. For eksempel inneholder klassene B, C og D alle variablene x, y og z i eksemplet nedenfor. Det er bare et spørsmål om tilgang.




// 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 };

 

 

Tabellen nedenfor oppsummerer de tre ovennevnte modusene og viser tilgangsspesifikasjonen for medlemmene av basisklassen i underklassen når den er avledet i offentlige, beskyttede og private moduser:

Typer arv:-

  1. Enkel arv
  2. Arv på flere nivåer
  3. Multippel arv
  4. Hierarkisk arv
  5. Hybrid arv

Typer av arv i C++

1. Enkeltarv :I enkeltarv har en klasse lov til å arve fra kun én klasse. dvs. én underklasse arves kun av én basisklasse.

Syntaks :

class subclass_name : access_mode base_class
{
  // body of subclass
};

OR

class A
{ 
... .. ... 
};

class B: public A
{
... .. ...
};




// C++ program to explain // Single inheritance #include<iostream> using namespace std; // base class class Vehicle {    public :      Vehicle()      {        cout << "This is a Vehicle\n" ;      } }; // 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; }

 

 

Utdata

This is a Vehicle




// Example: #include<iostream> using namespace std; class A {      protected :      int a;         public :          void set_A()          {              cout<< "Enter the Value of A=" ;              cin>>a;                       }          void disp_A()          {              cout<<endl<< "Value of A=" <<a;          } }; class B: public A {      int b,p;           public :          void set_B()          {              set_A();              cout<< "Enter the Value of B=" ;              cin>>b;          }                   void disp_B()          {              disp_A();              cout<<endl<< "Value of B=" <<b;          }                   void cal_product()          {              p=a*b;              cout<<endl<< "Product of " <<a<< " * " <<b<< " = " <<p;          }          }; main() {           B _b;      _b.set_B();      _b.cal_product();           return 0;      }

 

 

Utdata:- Angi verdien av A=3 3 Angi verdien av B=5 5 Produkt av 3 * 5 =15




// Example: #include<iostream> using namespace std; class A {      protected :      int a;         public :          void set_A( int x)          {               a=x;                     }             void disp_A()          {              cout<<endl<< "Value of A=" <<a;          } }; class B: public A {      int b,p;           public :          void set_B( int x, int y)          {              set_A(x);              b=y;          }                   void disp_B()          {              disp_A();              cout<<endl<< "Value of B=" <<b;          }                   void cal_product()          {              p=a*b;              cout<<endl<< "Product of " <<a<< " * " <<b<< " = " <<p;          }          }; main() {      B _b;      _b.set_B(4,5);      _b.cal_product();           return 0; }

 

 

Utdata

Product of 4 * 5 = 20

2. Multippel arv: Multiple Inheritance er en funksjon i C++ der en klasse kan arve fra mer enn én klasse. dvs. én underklasse er arvet fra mer enn én grunnklasse .

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 antall basisklasser være atskilt med komma (', ') og tilgangsmodusen for hver basisklasse må spesifiseres.




// C++ program to explain // multiple inheritance #include <iostream> using namespace std; // first base class class Vehicle { public :      Vehicle() { cout << "This is a Vehicle\n" ; } }; // second base class class FourWheeler { public :      FourWheeler()      {          cout << "This is a 4 wheeler Vehicle\n" ;      } }; // 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; }

 

 

Utdata

This is a Vehicle
This is a 4 wheeler Vehicle




// Example: #include<iostream> using namespace std; class A {                protected :                int a;                   public :                    void set_A()                    {                          cout<< "Enter the Value of A=" ;                          cin>>a;                              }                    void disp_A()                    {                          cout<<endl<< "Value of A=" <<a;                    } }; class B: public A {             protected :                  int b;                          public :                     void set_B()                  {                        cout<< "Enter the Value of B=" ;                         cin>>b;                     }                           void disp_B()                    {                       cout<<endl<< "Value of B=" <<b;                    } }; class C: public B {        int c,p;               public :            void set_C()            {                   cout<< "Enter the Value of C=" ;                   cin>>c;             }                      void disp_C()             {                   cout<<endl<< "Value of C=" <<c;             }                   void cal_product()               {                     p=a*b*c;                    cout<<endl<< "Product of " <<a<< " * " <<b<< " * " <<c<< " = " <<p;                } }; main() {           C _c;      _c.set_A();      _c.set_B();      _c.set_C();      _c.disp_A();      _c.disp_B();      _c.disp_C();      _c.cal_product();           return 0;      }

 

 

For å vite mer om det, vennligst se artikkelen Multiple Inheritances.

3. Flernivåarv :I denne typen arv opprettes en avledet klasse fra en annen avledet klasse.

Syntaks:-

class C
{ 
... .. ... 
};
class B:public C
{
... .. ...
};
class A: public B
{
... ... ...
};




// C++ program to implement // Multilevel Inheritance #include <iostream> using namespace std; // base class class Vehicle { public :      Vehicle() { cout << "This is a Vehicle\n" ; } }; // first sub_class derived from class vehicle class fourWheeler : public Vehicle { public :      fourWheeler()      {          cout << "Objects with 4 wheels are vehicles\n" ;      } }; // sub class derived from the derived base class fourWheeler class Car : public fourWheeler { public :      Car() { cout << "Car has 4 Wheels\n" ; } }; // main function int main() {      // Creating object of sub class will      // invoke the constructor of base classes.      Car obj;      return 0; }

 

 

Utdata

This is a Vehicle
Objects with 4 wheels are vehicles
Car has 4 Wheels

4. Hierarkisk arv :I denne typen arv arves mer enn én underklasse fra en enkelt basisklasse. dvs. mer enn én avledet klasse er opprettet 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.  
}   




// C++ program to implement // Hierarchical Inheritance #include <iostream> using namespace std; // base class class Vehicle { public :      Vehicle() { cout << "This is a Vehicle\n" ; } }; // 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; }

 

 

Utdata

This is a Vehicle
This is a Vehicle

5. Hybrid (virtuell) arv :Hybrid arv implementeres ved å kombinere mer enn én type arv. For eksempel:Kombinere hierarkisk arv og multippel arv.
Bildet nedenfor viser kombinasjonen av hierarkisk og multiple arv:




// C++ program for Hybrid Inheritance #include <iostream> using namespace std; // base class class Vehicle { public :      Vehicle() { cout << "This is a Vehicle\n" ; } }; // base class class Fare { public :      Fare() { cout << "Fare of Vehicle\n" ; } }; // 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; }

 

 

Utdata

This is a Vehicle
Fare of Vehicle




// Example: #include <iostream>  using namespace std;  class      protected      int a;       public      void get_a()               cout << "Enter the value of 'a' : "         cin>>a;       };     class B : public A        protected      int b;       public      void get_b()               cout << "Enter the value of 'b' : " ;         cin>>b;       };  class C        protected      int c;       public      void get_c()                cout << "Enter the value of c is : "          cin>>c;       };     class D : public B, public      protected      int d;       public      void mul()                 get_a();            get_b();            get_c();            cout << "Multiplication of a,b,c is : " <<a*b*c;       };  int main()       D d;       d.mul();       return 0;  }

 

 

6. Et spesielt tilfelle av hybridarv:Flerveisarv :
En avledet klasse med to baseklasser og disse to baseklassene har én felles baseklasse kalles flerveisarv. Tvetydighet kan oppstå i denne typen arv.
Eksempel:




// C++ program demonstrating ambiguity in Multipath // Inheritance #include <iostream> 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 << "\n a from ClassC  : " << obj.ClassC::a;      cout << "\n b : " << obj.b;      cout << "\n c : " << obj.c;      cout << "\n d : " << obj.d << '\n' ; }

 

 

Utdata

 a from ClassB  : 10
 a from ClassC  : 100
 b : 20
 c : 30
 d : 40

Utdata:

a from ClassB : 10
a from ClassC : 100
b : 20
c : 30
d : 40

In the above example, both ClassB and ClassC inherit ClassA, they both have a single copy of ClassA. However Class-D inherits both ClassB and ClassC, therefore Class-D has two copies of ClassA, one from ClassB and another from ClassC.
If we need to access the data member of ClassA through the object of Class-D, we must specify the path from which a will be accessed, whether it is from ClassB or ClassC, bcoz compiler can’t differentiate between two copies of ClassA in Class-D.

There are 2 Ways to Avoid this Ambiguity:

1) Avoiding ambiguity using the scope resolution operator: Using the scope resolution operator we can manually specify the path from which data member a will be accessed, as shown in statements 3 and 4, in the above example.




obj.ClassB::a = 10;       // Statement 3 obj.ClassC::a = 100;      // Statement 4

 

 

Note: Still, there are two copies of ClassA in Class-D.
2) Avoiding ambiguity using the virtual base class:




#include<iostream> 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 << "\n a : " << obj.a;      cout << "\n b : " << obj.b;      cout << "\n c : " << obj.c;      cout << "\n d : " << obj.d << '\n' ; }

 

 

Utdata:

a : 100
b : 20
c : 30
d : 40

According to the above example, Class-D has only one copy of ClassA, therefore, statement 4 will overwrite the value of a, given in statement 3.

Denne artikkelen er bidratt av Harsh Agarwal . Hvis du liker GeeksforGeeks og ønsker å bidra, kan du også skrive en artikkel ved å bruke write.geeksforgeeks.org eller sende artikkelen til [email protected]. Se artikkelen din som vises på GeeksforGeeks hovedside og hjelp andre nerder.