Differences

This shows you the differences between two versions of the page.

Link to this comparison view

poo-is-ab:laboratoare:06 [2025/09/23 20:03]
razvan.cristea0106
poo-is-ab:laboratoare:06 [2025/11/03 21:02] (current)
razvan.cristea0106 [Moștenirea între două clase]
Line 9: Line 9:
   * recunoască și să înțeleagă conceptul de moștenire între două clase   * recunoască și să înțeleagă conceptul de moștenire între două clase
   * construiască legături între clase folosind relația de tip "​is-a"​ (relație de specializare)   * construiască legături între clase folosind relația de tip "​is-a"​ (relație de specializare)
-  * folosească membrii marcați cu protected și să înțeleagă diferențele dintre ​accesul public, privat și protejat în moștenire+  * folosească membrii marcați cu protected și să înțeleagă diferențele dintre ​tipurile de acces
   * aplice principiile de reutilizare a codului prin extinderea funcționalității clasei de bază în clasa derivată   * aplice principiile de reutilizare a codului prin extinderea funcționalității clasei de bază în clasa derivată
  
Line 21: Line 21:
 Așa cum am menționat anterior, **moștenirea** este un principiu fundamental al **POO** care permite unei **clase derivate** să preia atât **proprietățile (atributele)** cât și **comportamentele (funcțiile membre)** unei **clase părinte**. Prin acest mecanism, **clasa derivată** poate să extindă funcționalitatea moștenită prin adăugarea de noi atribute și metode sau prin redefinirea celor existente. Scopul principal al **moștenirii** este de a promova **reutilizarea codului** și de a permite o **extensie** naturală a funcționalităților inițiale, astfel încât să se creeze o structură mai **flexibilă** și mai **ușor de întreținut** în cadrul aplicațiilor. Așa cum am menționat anterior, **moștenirea** este un principiu fundamental al **POO** care permite unei **clase derivate** să preia atât **proprietățile (atributele)** cât și **comportamentele (funcțiile membre)** unei **clase părinte**. Prin acest mecanism, **clasa derivată** poate să extindă funcționalitatea moștenită prin adăugarea de noi atribute și metode sau prin redefinirea celor existente. Scopul principal al **moștenirii** este de a promova **reutilizarea codului** și de a permite o **extensie** naturală a funcționalităților inițiale, astfel încât să se creeze o structură mai **flexibilă** și mai **ușor de întreținut** în cadrul aplicațiilor.
  
-Înainte de a explica moștenirea între două clase vom face o scurtă ​recapitulare ​noțiunilor deja învățate ​în cadrul laboratoarelor anterioare. Pentru acest laborator propunem clasa **Locuinta** care are ca și membri **pret (de tip float)** și **adresa (șir de caractere alocat dinamic)**.+Înainte de a explica moștenirea între două clase vom face o scurtă ​prezentare ​modului ​în care trebuie să gestionăm mai multe fișiere header într-un proiect. Pentru acest laborator propunem clasa **Locuinta** care are ca și membri **pret (de tip float)** și **adresa (șir de caractere alocat dinamic)**.
  
 <code cpp> <code cpp>
Line 30: Line 30:
 class Locuinta class Locuinta
 { {
- float pret; +    ​float pret; 
- char* adresa;+    char* adresa;
  
 public: public:
  
- Locuinta();​ +    ​Locuinta();​ 
- Locuinta(const float& pret, const char* adresa); +    Locuinta(const float& pret, const char* adresa); 
- Locuinta(const Locuinta&​ locuinta);​ +    Locuinta(const Locuinta&​ locuinta);​ 
- Locuinta&​ operator=(const Locuinta&​ locuinta);​ +    Locuinta&​ operator=(const Locuinta&​ locuinta);​ 
- ~Locuinta();​+    ~Locuinta();​
  
- float getPret() const; +    ​float getPret() const; 
- char* getAdresa() const;+    char* getAdresa() const;
  
- void setPret(const float& pret); +    ​void setPret(const float& pret); 
- void setAdresa(const char* adresa);+    void setAdresa(const char* adresa);
  
- friend std::​ostream&​ operator<<​(std::​ostream&​ out, const Locuinta&​ locuinta);+    ​friend std::​ostream&​ operator<<​(std::​ostream&​ out, const Locuinta&​ locuinta);
 }; };
 </​code>​ </​code>​
Line 53: Line 53:
 <​note>​Pe prima linie a **fișierului header** în care este definită clasa **Locuinta**,​ putem observa utilizarea directivei **''#​pragma once''​**. Aceasta este o instrucțiune specifică compilatorului care indică faptul că fișierul respectiv trebuie inclus și compilat o **singură dată**, chiar dacă este referit în mod repetat în alte fișiere prin intermediul directivelor **''#​include''​**. Astfel, se previn **multiplele incluziuni** ale aceluiași fișier header, care ar putea duce la erori de compilare, cum ar fi redefinirea claselor sau funcțiilor. Directiva **''#​pragma once''​** este o alternativă modernă și mai simplă la gardienii clasici ai fișierelor header, adică acele secvențe de cod cu **''#​ifndef''​**,​ **''#​define''​** și **''#​endif''​** care au același scop.</​note>​ <​note>​Pe prima linie a **fișierului header** în care este definită clasa **Locuinta**,​ putem observa utilizarea directivei **''#​pragma once''​**. Aceasta este o instrucțiune specifică compilatorului care indică faptul că fișierul respectiv trebuie inclus și compilat o **singură dată**, chiar dacă este referit în mod repetat în alte fișiere prin intermediul directivelor **''#​include''​**. Astfel, se previn **multiplele incluziuni** ale aceluiași fișier header, care ar putea duce la erori de compilare, cum ar fi redefinirea claselor sau funcțiilor. Directiva **''#​pragma once''​** este o alternativă modernă și mai simplă la gardienii clasici ai fișierelor header, adică acele secvențe de cod cu **''#​ifndef''​**,​ **''#​define''​** și **''#​endif''​** care au același scop.</​note>​
  
-Dacă voiam să folosim varianta tradițională de scriere a unui fișier header am fi procedat ​în maniera următoare.+Dacă am dori să folosim varianta tradițională de scriere a unui fișier header, astfel încât acesta să fie inclus o singură dată, ​am putea proceda ​în maniera următoare.
  
 <code cpp> <code cpp>
Line 107: Line 107:
 class Apartament : public Locuinta // clasa Apartament mosteneste clasa Locuinta class Apartament : public Locuinta // clasa Apartament mosteneste clasa Locuinta
 { {
- int numarCamere;​ +    ​int numarCamere;​ 
- char* numeProprietar;​+    char* numeProprietar;​
  
 public: public:
  
- Apartament();​ +    ​Apartament();​ 
- Apartament(const float& pret, const char* adresa, const int& numarCamere,​ const char* numeProprietar);​ +    Apartament(const float& pret, const char* adresa, const int& numarCamere,​ const char* numeProprietar);​ 
- Apartament(const Apartament&​ apartament);​ +    Apartament(const Apartament&​ apartament);​ 
- Apartament&​ operator=(const Apartament&​ apartament);​ +    Apartament&​ operator=(const Apartament&​ apartament);​ 
- ~Apartament();​+    ~Apartament();​
  
- int getNumarCamere() const; +    ​int getNumarCamere() const; 
- char* getNumeProprietar() const;+    char* getNumeProprietar() const;
  
- void setNumarCamere(const int& numarCamere);​ +    ​void setNumarCamere(const int& numarCamere);​ 
- void setNumarCamere(const char* numeProprietar);​+    void setNumeProprietar(const char* numeProprietar);​
  
- friend std::​ostream&​ operator<<​(std::​ostream&​ out, const Apartament&​ apartament);​+    ​friend std::​ostream&​ operator<<​(std::​ostream&​ out, const Apartament&​ apartament);​
 }; };
 </​code>​ </​code>​
Line 143: Line 143:
 protected: // specificatorul de acces protected protected: // specificatorul de acces protected
  
- float pret; +    ​float pret; 
- char* adresa;+    char* adresa;
  
 public: public:
  
- Locuinta();​ +    ​Locuinta();​ 
- Locuinta(const float& pret, const char* adresa); +    Locuinta(const float& pret, const char* adresa); 
- Locuinta(const Locuinta&​ locuinta);​ +    Locuinta(const Locuinta&​ locuinta);​ 
- Locuinta&​ operator=(const Locuinta&​ locuinta);​ +    Locuinta&​ operator=(const Locuinta&​ locuinta);​ 
- ~Locuinta();​+    ~Locuinta();​
  
- float getPret() const; +    ​float getPret() const; 
- char* getAdresa() const;+    char* getAdresa() const;
  
- void setPret(const float& pret); +    ​void setPret(const float& pret); 
- void setAdresa(const char* adresa);+    void setAdresa(const char* adresa);
  
- friend std::​ostream&​ operator<<​(std::​ostream&​ out, const Locuinta&​ locuinta);+    ​friend std::​ostream&​ operator<<​(std::​ostream&​ out, const Locuinta&​ locuinta);
 }; };
 </​code>​ </​code>​
Line 179: Line 179:
 Apartament::​Apartament() : Locuinta() Apartament::​Apartament() : Locuinta()
 { {
- numarCamere = 0; +    ​numarCamere = 0; 
- numeProprietar = nullptr;+    numeProprietar = nullptr;
 } }
 </​code>​ </​code>​
Line 191: Line 191:
 Apartament::​Apartament(const float& pret, const char* adresa, const int& numarCamere,​ const char* numeProprietar) : Locuinta(pret,​ adresa) Apartament::​Apartament(const float& pret, const char* adresa, const int& numarCamere,​ const char* numeProprietar) : Locuinta(pret,​ adresa)
 { {
- this->​numarCamere = numarCamere;​+    ​this->​numarCamere = numarCamere;​
  
- if (numeProprietar != nullptr) +    ​if (numeProprietar != nullptr) 
-+    
- this->​numeProprietar = new char[strlen(numeProprietar) + 1]; +        this->​numeProprietar = new char[strlen(numeProprietar) + 1]; 
- strcpy(this->​numeProprietar,​ numeProprietar);​ +        strcpy(this->​numeProprietar,​ numeProprietar);​ 
-+    
- else +    else 
-+    
- this->​numeProprietar = nullptr; +        this->​numeProprietar = nullptr; 
- }+    }
 } }
 </​code>​ </​code>​
Line 214: Line 214:
 Apartament::​Apartament(const Apartament&​ apartament) : Locuinta(apartament) Apartament::​Apartament(const Apartament&​ apartament) : Locuinta(apartament)
 { {
- numarCamere = apartament.numarCamere;​+    ​numarCamere = apartament.numarCamere;​
  
- if (apartament.numeProprietar != nullptr) +    ​if (apartament.numeProprietar != nullptr) 
-+    
- numeProprietar = new char[strlen(apartament.numeProprietar) + 1]; +        numeProprietar = new char[strlen(apartament.numeProprietar) + 1]; 
- strcpy(numeProprietar,​ apartament.numeProprietar);​ +        strcpy(numeProprietar,​ apartament.numeProprietar);​ 
-+    
- else +    else 
-+    
- numeProprietar = nullptr; +        numeProprietar = nullptr; 
- }+    }
 } }
 </​code>​ </​code>​
Line 237: Line 237:
 Apartament::​~Apartament() Apartament::​~Apartament()
 { {
- if (numeProprietar != nullptr) +    ​if (numeProprietar != nullptr) 
-+    
- delete[] numeProprietar;​ +        delete[] numeProprietar;​ 
- }+    }
 } }
 </​code>​ </​code>​
Line 253: Line 253:
 Apartament&​ Apartament::​operator=(const Apartament&​ apartament) Apartament&​ Apartament::​operator=(const Apartament&​ apartament)
 { {
- if (this == &​apartament) +    ​if (this == &​apartament) 
-+    
- return *this; +        return *this; 
- }+    } 
 + 
 +    this->​Locuinta::​operator=(apartament);​ // se apeleaza operatorul de asignare din clasa parinte 
 +    /​*(Locuinta&​)(*this) = apartament; // este echivalent cu linia de mai sus doar ca este o alta forma de apel*/
  
- this->​Locuinta::​operator=(apartament); // se apeleaza operatorul de asignare din clasa parinte +    if (numeProprietar !nullptr) 
- /​*(Locuinta&​)(*this) = apartament; // este echivalent cu linia de mai sus doar ca este o alta forma de apel*/+    { 
 +        delete[] numeProprietar
 +    }
  
- numarCamere = apartament.numarCamere;​+    ​numarCamere = apartament.numarCamere;​
  
- if (apartament.numeProprietar != nullptr) +    ​if (apartament.numeProprietar != nullptr) 
-+    
- numeProprietar = new char[strlen(apartament.numeProprietar) + 1]; +        numeProprietar = new char[strlen(apartament.numeProprietar) + 1]; 
- strcpy(numeProprietar,​ apartament.numeProprietar);​ +        strcpy(numeProprietar,​ apartament.numeProprietar);​ 
-+    
- else +    else 
-+    
- numeProprietar = nullptr; +        numeProprietar = nullptr; 
- }+    }
  
- return *this;+    ​return *this;
 } }
 </​code>​ </​code>​
Line 284: Line 289:
 std::​ostream&​ operator<<​(std::​ostream&​ out, const Apartament&​ apartament) std::​ostream&​ operator<<​(std::​ostream&​ out, const Apartament&​ apartament)
 { {
- operator<<​(out,​ (Locuinta&​)apartament);​ // chemam operatorul << din clasa parinte+    ​operator<<​(out,​ (Locuinta&​)apartament);​ // chemam operatorul << din clasa parinte 
 +    /*out << (Locuinta&​)apartament;​ // o alta forma de a chema operatorul << din clasa parinte*/
  
- out << "​Numarul de camere din apartament este: " << apartament.numarCamere << " ron\n";​+    ​out << "​Numarul de camere din apartament este: " << apartament.numarCamere << " ron\n";​
  
- if (apartament.numeProprietar != nullptr) +    ​if (apartament.numeProprietar != nullptr) 
-+    
- out << "​Numele proprietarului este: " << apartament.numeProprietar << "​\n";​ +        out << "​Numele proprietarului este: " << apartament.numeProprietar << "​\n";​ 
-+    
- else +    else 
-+    
- out << "​Numele proprietarului este: N/​A\n";​ +        out << "​Numele proprietarului este: N/​A\n";​ 
- }+    }
  
- return out;+    ​return out;
 } }
 </​code>​ </​code>​
  
-<note warning>​**Funcțiile friend** dintr-o clasă **nu** se moștenesc automat de către **clasa derivată**,​ motiv pentru care trebuie să apelăm explicit **operatorul %%<<​%%** definit în **clasa de bază**. Pentru a înțelege mai bine acest comportament,​ putem face următoarea analogie: prietenii părinților ​voștri **nu sunt neapărat** și prietenii ​voștri. Relația de prietenie este specifică **doar** între părinții ​voștri și acele persoane, iar aceasta **nu se extinde automat** asupra ​voastră. La fel, funcțiile **friend** sunt prietene ale **clasei părinte**, dar **nu** devin prietene implicit și pentru **clasa derivată**.</​note>​+<note warning>​**Funcțiile friend** dintr-o clasă **nu** se moștenesc automat de către **clasa derivată**,​ motiv pentru care trebuie să apelăm explicit **operatorul %%<<​%%** definit în **clasa de bază**. Pentru a înțelege mai bine acest comportament,​ putem privi lucrurile astfel: prietenii părinților ​noștri **nu sunt neapărat** și prietenii ​noștri. Relația de prietenie este specifică **doar** între părinții ​noștri și acele persoane, iar aceasta **nu se extinde automat** asupra ​noastră. La fel, funcțiile **friend** sunt prietene ale **clasei părinte**, dar **nu** devin prietene implicit și pentru **clasa derivată**.</​note>​
  
 ==== ==== ==== ====
poo-is-ab/laboratoare/06.1758646987.txt.gz · Last modified: 2025/09/23 20:03 by razvan.cristea0106
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0