Moștenire

Mostenirea rerpezintă proprietatea claselor de a “da naștere”, pe baza datelor membre și a metodelor, altor clase. Clasele inițiale se numesc, în acest caz, clase părinți, cele din urmă fiind clase copil. Evidenti, cele din urmă pot avea propriile lor atribute sau funcții membru. Un exemplu rapid poate fi dat imaginându-ne clasa persoană, pe baza căreia poate fi, ușor construită clasa angajat. Mecanismul prin care, pronind de la o clasă părinte este creată o clasă copil se numește derivare.

O clasă derivată moștenește de la clasa de bază toate metodele acesteia, mai puțin;

• contructorii și destructorii

• operatorii supraîncărcați

• funcțiile friend

Sintaxa generală pentru declararea unei clase derivate este:

```
class id_clasa_copil: specificator_acces id_clasa_parinte;

```

În declarația anterioară specificator\_acces poate avea valorile:public, protected, sau private, Dacă nu este specificat, este considerat, implicit, private.

De obicei, specificatorul de acces este public. Prin intermediul acestuia, membrii publici ai clasei de bază devin membri publici ai clasei derivate, iar cei protejați devin protejați. Membrii privați ai unei clase părinte nu pot fi accesați direct de clasele copil, ci doar prin accesarea metodelor publice sau protejate ale părintelui.  Moștenirea prin specificatorul protected face ca membrii publici și cei protejați să devină membri protejați ai clasei copil. În fine, derivarea sub clauza private duce latransformarea membrilor publici sau protejați ai clasei de bază în membri privați ai clasei derivate.

În funcție de identificatorii de acces folosiți la nivelul membrilor, putem face următoarea reprezentare:

 **În clasa de bază**
 **În clasa derivată**
 **În clase independente**

Să analizăm exemplul următor:

```
#include <iostream>

using namespace std;

struct data
{

    int z,l,a;
};

class persoana
{

protected:
   char nume[100];
   data data_nasterii;

public:
   persoana(void)
   {
       nume[0]=0;
       data_nasterii.z=1;
       data_nasterii.l=1;
       data_nasterii.a=2000;
   }

   ~persoana()
   {
       cout<<"\n obiectul persoana distrus";
   }

   void initializeaza()
   {
       cout<<'\n';
       cin.getline(nume, 100);
       cin>>data_nasterii.z>>data_nasterii.l>>data_nasterii.a;
   }

   void afiseaza()
   {
       cout<<nume<<'\t'<<data_nasterii.z<<'.'<<data_nasterii.l<<'.'<<data_nasterii.a;
   }
};

class elev: public persoana
  {

private:
   int numar_matricol;
   char clasa[3];

public:
   elev(void)
   {
       numar_matricol=0;
       clasa[0]=0;
   }
   ~elev()
   {
       cout<<"\n obiectul elev distrus";
   }

   void initializeaza2()
   {
       cout<<'\n';
       cin.getline(nume, 100);
       cin>>data_nasterii.z>>data_nasterii.l>>data_nasterii.a;
       cin>>numar_matricol;
       cin.get();
       cin.getline(clasa, 4);
   }

   void afiseaza2()
   {
       cout<<nume<<'\t'<<data_nasterii.z<<'.'<<data_nasterii.l<<'.'<<data_nasterii.a<<'\t'<<numar_matricol<<'\t'<<clasa;
   }
};

int main()
  {
   elev e;
   e.initializeaza2();
   e.afiseaza2();
   return 0;
  }

```

Clasa elev derivă din clasa persoana, de la care moștenește datele membre nume, respectiv data\_nasterii. Fiind declarate sub clauza protected, clasa elev va avea acces la ele, acestea păstrându-și caracterul protejat și pentru eventualele clase ce vor fi derivate din aceasta, întrucât derivarea s-a făcut cu specificatorul de acces public.

Deși obiectele de tip elev au acces la metodele clasei persoana, am ales să definim metodele intializeaza2() și afiseaza2(), fiind vorba de un set extins de date membru. Am ales să afișăm un mesaj în corpul funcției destructor pentru a pune în evidență că instanțierea unui obiect elev se face pe baza instanțierii unui obiect persoana. Din această cauză, vor fi apelați ambii destructori, obținând mesaje aparent ambigue.

În afara cazului comun, în care o clasă are un părinte, există și situații în care aceasta poate moșteni mai multe clase. Situația se numește moștenire multiplă. Derivarea unei clase de la mai multe clase de bază se face prin sintaxa:

```
class id_clasa_copil: specificator_acces:id_clasa1, specificator_acces: id_clasa 2…

```

Ca și în cazul moștenirii simple, specificator\_acces poate fi public, protected sau private, precizând în cazul fiecărei clase moștenite cum vor fi preluați membrii acesteia.