Sunteți pe pagina 1din 7

Derivare și moștenire

– sintaxa;
– de ce derivăm ?
• reutilizare cod sursa si cod obiect ( biblioteci de clase: MFC, OWL, FCL );
• obţinerea unei superclase fară recompilarea clasei iniţiale;
– derivarea reflectă o înrudire; modelează legături reale; Rockfort Lhotka, Business
Objects, 2008
– inheritance (is a) versus composition (has a)
– nici prin derivare, nici prin includere nu câstigăm drepturi de acces speciale;
– tipul derivării nu poate surclasa restricțiile de acces, dar poate introduce altele noi!
• protected – tot ce e accesibil devine protected
• private - tot ce e accesibil devine private
• public – lasă tot ce e accesibil cum erau; private rămâne inaccesibil
• publicizare dacă nu dorim să se aplice la tot domeniul;
– friend se moștenește, dar doar pentru zona moștenită:

friend ostream & operator<<(ostream& os, Muncitor &m)


{
os << (Pers&)m; // partea mostenita
os << "\tnrPiese: " << m.nrPiese << "\tmanPiesa: " << m.manPiesa;
return os;
}
Derivare și moștenire

public
public

Derivare
private public Inaccesibil

protected protected

(a)

private
public

Derivare
private Inaccesibil
private

protected private

(b)

protected
public

Derivare
private protected Inaccesibil

protected protected
(c)

Fig. 3.1 Moștenirea drepturilor de acces prin derivare


Derivare și moștenire
– conlucrare constructori (explicit; dacă nu, implicit !); altfel n-ar putea opera pe private;
Muncitor(int m = 355, double s = 3000,
const char* n = "Dorel", int nrP = 1, double manP = 155.)
: /* Pers(m, s, n), */ manPiesa(manP)
{
nrPiese = nrP; cout << "\n cons D:: ";
}
– conlucrare constructori copiere: copy cons implicit, sintetizat dacă nu există
Muncitor(Muncitor &m) : Pers(m)
{
nrPiese = m.nrPiese; manPiesa = m.manPiesa;
cout << "\n copy cons D:: ";
}

‒ ordinea de apel a constructorilor: constructor B, apoi constructor D; regula


se aplică recursiv, dacă se derivează pe mai multe niveluri;
– ordinea de apel este inversă la destructori (destructor D, apoi destructor B)
– upcasting: conversii implicite de obiecte, pointeri şi referinţe, pe direcția is a :
• conversii de obiecte b=d; // decupeaza doar zona mostenita
• conversii de pointeri si referinte pb = pd; // modifica adrese; nu e doar formala
– downcasting: conversii de pointeri de membri, pe directia inversa lui is a;
Derivare și moștenire
– Când clasa derivată nu are supraîncărcat operator= compilatorul scrie o versiune de
copiere a datelor membre moştenite apelând la supraîncărcarea operatorului de
atribuire definit în clasa de bază (sau pus de compilator, când nu există), iar datele
membre specifice vor fi copiate bit cu bit
– Când clasa derivată are supraîncărcat operator= atunci acesta va realiza copierea
tuturor datelor membre, eventual apelând la operator= din baza

Muncitor& operator=(Muncitor &src)


{
if (this != &src)
{
Pers::operator= (src);
// preluare parte mostenita; src& convert in Pers&
manPiesa = src.manPiesa;
nrPiese = src.nrPiese;
}
cout << "\n op= D:: ";
return *this;
}
– dar operator cast ? Vehicul , Autoturism, Impoziteaza
Derivare și moștenire

– cum se mostenesc funcţiile; 3 supraincărcări ale operator* in Pers (calcul


primă) şi continui pe Muncitor, cu încă o supraincarcare (procentul de
premiere pe salariu realizat efectiv); cum distinge ?
– dacă f() are acelaşi prototip cu încă o supraîncărcare ? d.B::f();
– dar daca facem b = d; si apoi apelam b.f() ? Obiectul e cel care califică (se
apeleaza versiunea din baza!)

– cum se mostenesc operatorii ?


• ascunderea (in forma scurta de apel): d+i inseamna operator+ din
derivata
• sunt apelabili in forma lunga, folosind rezolutie de clasa :
d.B::operator+(i);
Derivare și moștenire
– virtualizare: se bazeaza pe apel de metode prin pointeri de functii;
– vtable; *pVTable - obiectele devin mai mari !
– ex. Animal, Horse, Bird;
– de ce nu se poate virtualiza pornind de la obiecte ?; (la upcasting se taie din obiect si
functiile virtuale n-ar avea datele de lucru necesare)
– virtualizarea cu referinta presupune ( un nivel intermediar ) apel de functie cu transfer
prin referinta; ( remember interpretarea referintei in C++ si in Java/C#)

sort(Comparator & ord);

• ordinea ord poate fi data prin referinta de obiecte MaiMic, MaiMare, MyOrd etc.
care au supraincarcat corespunzator operator()()

– funcții virtual pure; clase abstracte; conceptul interface

– anomalii la virtualizare:
• destructori virtuali (de pus virtual, pentru test)
• apel de functii virtuale in constructor
– comparator virtual (cod sursa)
Mecanismul de virtualizare:
tabela de functii virtuale

pVTable

D 0 1 2 3 4

vTable

S-ar putea să vă placă și