Introducere
Derivarea claselor (moștenirea) este unul dintre principiile fundamentale ale programării orientate pe obiecte. Ne permite să definim o clasă pornind de la altă clasă, creată anterior, și facilitează crearea și întreținerea aplicațiilor. Tototdată permite reutilizarea codului și micșorează timpul de implementare a programelor.
La crearea unei clase, în loc să scriem date și funcții membre complet noi, putem să precizăm că noua clasă va moșteni membri unei clase existente. Se obțin astfel ierarhii de clase.
Moștenirea are sens numai când obiectele din clasa moștenită fac parte din obiectele clasei de bază – relația dintre ele este de tipul Is A (este un/o). De exemplu:
- paralelogramul este un patrulater. Clasa
Paralelogrampoate fi derivată din clasaPatrulater. - câinele este un animal. Clasa
Cainepoate fi derivată din clasaAnimal.
Terminologie
Fie B o clasă care există deja, iar D clasa care moștenește membrii clasei B. Spunem că:
Beste clasa de bază;Deste clasa derivată;- clasa
Ds-a obținut prin derivarea claseiB; - clasa
Ba fost derivată și s-a obținut clasaD; - clasa
Dmoștenește clasaB; - relația de moștenire se reprezintă prin următoarea diagramă:

În C++, o clasă poate fi derivată pornind de la mai multe clase de bază. Totodată, specificatorii de acces cunoscuți (public, private, protected) sunt folosiți și pentru a preciza modul în care se face derivarea. Efectul lor este legat de vizibilitatea membrilor clasei de bază în clasa derivată.
Derivarea unei clase
Cea mai simplă formă de derivarea a unei clase este prezentată mai jos:
class D: public B{
// membri noi ai clasei derivate
}
Observații:
- clasa
Beste clasa de bază, care trebuie să fie deja definită; - clasa
Deste clasa derivată; - specificatorul de acces folosit în exemplu,
public, face ca:- membrii
publicdin clasa de bazăBrămânpublicși în clasa derivatăD– pot fi accesați din afara claseiD; - membrii
protecteddin clasa de bazăBrămânprotectedși în clasa derivatăD– pot fi accesați din clasa derivataDși vor putea fi acesați din alte clase vor moșteni clasaD; - membrii
privatedin clasa de bazăBnu pot fi accesați din clasa derivatăD;
- membrii
- la definiția clasei derivate, în loc de
publicputem folosiprivatesauprotected. Semnificația lor va fi discutată ceva mai târziu!
Exemplu

#include<iostream>
using namespace std;
class Animal{
private:
protected:
int varsta;
public:
Animal(){
varsta = 0;
cout << "S-a nascut un animal." << endl;
}
~Animal(){
cout << "Animalul a murit." << endl;
}
void creste()
{
++ varsta;
cout << "Animalul are " << varsta << (varsta == 1 ? " an":" ani") << endl;
}
};
class Caine: public Animal{
public:
Caine(){
cout << "S-a nascut un caine." << endl;
}
~Caine(){
cout << "Cainele a murit." << endl;
}
void latra()
{
for(int i = 1 ; i <= varsta ; i ++)
cout << "Ham " ;
cout << endl;
}
void creste()
{
++ varsta;
cout << "Cainele are " << varsta << (varsta == 1 ? " an":" ani") << endl;
}
};
int main(){
Caine X;
X.creste();
X.Animal::creste();
X.latra();
X.creste();
X.latra();
}
S-a nascut un animal. S-a nascut un caine. Cainele are 1 an Animalul are 2 ani Ham Ham Cainele are 3 ani Ham Ham Ham Cainele a murit. Animalul a murit.
Observații
Animaleste clasa de bază, iarCaineeste clasa derivată;- din clasa derivată (metoda
latra()) am accesat proprietateavarstadin clasa de bază:- acest lucru a fost posibil deoarece proprietatea
varstaa fost declaratăprotected - dacă ar fi fost declarată
private, nu putea fi accesată din clasa derivată
- acest lucru a fost posibil deoarece proprietatea
- din exterior – funcția
main(), pentru obiectulXde tipCaineam accesat:- metoda
latra(), disponibilă doar în clasa derivată; - metoda
creste(), moștenită din clasa de bază; - ambele metode sunt publice în clasa derivată;
- metoda
- ambele clase sunt înzestrate cu constructori și destructori:
- în cazul constructorului, mai întâi se apeleaza cel al clasei de bază, apoi cel al clasei derivate;
- în cazul destructorului, ordinea este inversă;
- dacă în clasa de bază și în clasa derivată avem doi membri cu același nume (overriding), prioritate are cel din clasa derivată. Pentru a-l accesa pe cel din clasa de bază vom folosi operatorul de rezoluție:
X.creste(); // Cainele are 1 an
X.Animal::creste(); // Animalul are 2 ani - în exemplul de mai jos se evidențiază modul în care se poate face atribuirea între o variabilă de tipul clasei de bază și una de tipul clasei derivate:
int main(){ Caine X; X.creste(); // Cainele are 1 an X.latra(); // Ham Animal A; A = X; A.creste(); // Animalul are 2 ani // X = A; eroare de sintaxă
}
Aeste de tipulAnimal(clasa de bază), iarXeste de tipulCaine(clasa derivată). Atunci:- atribuirea
A = X;este corectă. ÎnAse vor copia doar membri dinXcare fac parte din clasa de bază. - atribuirea
X = A;nu este corectă. Clasa derivată conține și membri care nu aparțin clasei de bază, ce nu pot fi inițializați prin această atribuire!
- atribuirea
Accesul la membrii claselor derivate
Accesul la membrii (date sau funcții) clasei de bază în clasa derivată se face în funcție de regulile de acces la membrii clasei de bază și în funcție de modalitatea în care s-a făcut derivarea.
Sunt trei moduri de declarare a membrilor unei clase:
- publici –
public– pot fi accesați din afara clasei, dar și din interiorul ei - protejati –
protected– nu pot fi accesați din exteriorul clasei (de bază sau derivate). Pot fi accesați din interiorul clasei de bază și din interiorul claselor derivate - privați –
private– pot fi accesați numai din interiorul clasei.
Modalitățile de derivarea ale unei clase sunt:
- derivare publică:
class D: public B{ … }- membrii publici ai clasei
Brămân publici și în clasaD; - membrii protejați al clasei
Brămân protejați în clasaD; - membrii privați ai clasei
Bsunt inaccesibili în clasaD;
- membrii publici ai clasei
- derivare protejată:
class D: protected B{ … }- membrii publici ai clasei
Bdevin protejați și în clasaD; - membrii protejați al clasei
Brămân protejați în clasaD; - membrii privați ai clasei
Bsunt inaccesibili în clasaD;
- membrii publici ai clasei
- derivare privată:
class D: private B{ … }- membrii publici ai clasei
Bdevin privați și în clasaD; - membrii protejați al clasei
Bdevin privați în clasaD; - membrii privați ai clasei
Bsunt inaccesibili în clasaD;
- membrii publici ai clasei