Differences

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

Link to this comparison view

poo-is-ab:laboratoare:10 [2025/09/23 20:14]
razvan.cristea0106
poo-is-ab:laboratoare:10 [2025/12/01 13:40] (current)
razvan.cristea0106 [Supraîncărcarea operatorului << pentru o clasă abstractă]
Line 15: Line 15:
 ==== Introducere ==== ==== Introducere ====
  
-În acest laborator vom aprofunda utilizarea **claselor abstracte** și a **interfețelor**,​ concentrându-ne pe un aspect important al **POO** și anume gestionarea colecțiilor de date **neomogene**. Dacă până acum am lucrat cu **pointeri** pentru a manipula obiecte derivate din **clase abstracte** sau **interfețe**,​ acum vom explora cum putem organiza și gestiona aceste obiecte utilizând colecții de date, cum ar fi **vectorii**. Pentru o mai bună înțelegere a noțiunilor legate de **clase abstracte** și **interfețe** se recomandă citirea [[poo-is-ab:​laboratoare:​08|laboratorului 9]].+În acest laborator vom aprofunda utilizarea **claselor abstracte** și a **interfețelor**,​ concentrându-ne pe un aspect important al **POO** și anume gestionarea colecțiilor de date **neomogene**. Dacă până acum am lucrat cu **pointeri** pentru a manipula obiecte derivate din **clase abstracte** sau **interfețe**,​ acum vom explora cum putem organiza și gestiona aceste obiecte utilizând colecții de date, cum ar fi **vectorii**. Pentru o mai bună înțelegere a noțiunilor legate de **clase abstracte** și **interfețe** se recomandă citirea [[poo-is-ab:​laboratoare:​09|laboratorului 9]].
  
 ==== Vector de obiecte neomogene ==== ==== Vector de obiecte neomogene ====
Line 40: Line 40:
 public: public:
  
- virtual ~ProdusElectronic() = 0; // destructor virtual pur+    ​virtual ~ProdusElectronic() = 0; // destructor virtual pur
  
- virtual float getPret() const = 0; +    ​virtual float getPret() const = 0; 
- virtual char* getProducator() const = 0;+    virtual char* getProducator() const = 0;
 }; };
 </​code>​ </​code>​
Line 54: Line 54:
 ProdusElectronic::​~ProdusElectronic() ProdusElectronic::​~ProdusElectronic()
 { {
- // chiar daca nu scriem nimic este necesar sa existe pentru a putea functiona corect dezalocarea memoriei+    ​// chiar daca nu scriem nimic este necesar sa existe pentru a putea functiona corect dezalocarea memoriei
 } }
 </​code>​ </​code>​
Line 63: Line 63:
 class Laptop : public ProdusElectronic class Laptop : public ProdusElectronic
 { {
- float pret; +    ​float pret; 
- char* producator;+    char* producator;
  
 public: public:
  
- Laptop(); +    ​Laptop(); 
- Laptop(const float& pret, const char* producator);​ +    Laptop(const float& pret, const char* producator);​ 
- ~Laptop();+    ~Laptop();
  
- float getPret() const override; +    ​float getPret() const override; 
- char* getProducator() const override;+    char* getProducator() const override;
 }; };
 </​code>​ </​code>​
Line 80: Line 80:
 class SmartPhone : public ProdusElectronic class SmartPhone : public ProdusElectronic
 { {
- float pret; +    ​float pret; 
- char* producator;+    char* producator;
  
 public: public:
  
- SmartPhone();​ +    ​SmartPhone();​ 
- SmartPhone(const float& pret, const char* producator);​ +    SmartPhone(const float& pret, const char* producator);​ 
- ~SmartPhone();​+    ~SmartPhone();​
  
- float getPret() const override; +    ​float getPret() const override; 
- char* getProducator() const override;+    char* getProducator() const override;
 }; };
 </​code>​ </​code>​
Line 99: Line 99:
 Laptop::​Laptop() Laptop::​Laptop()
 { {
- pret = 0.0f; +    ​pret = 0.0f; 
- producator = nullptr;+    producator = nullptr;
 } }
  
 Laptop::​Laptop(const float& pret, const char* producator) Laptop::​Laptop(const float& pret, const char* producator)
 { {
- this->​pret = pret;+    ​this->​pret = pret;
  
- if (producator != nullptr) +    ​if (producator != nullptr) 
-+    
- this->​producator = new char[strlen(producator) + 1]; +        this->​producator = new char[strlen(producator) + 1]; 
- strcpy(this->​producator,​ producator);​ +        strcpy(this->​producator,​ producator);​ 
-+    
- else +    else 
-+    
- this->​producator = nullptr; +        this->​producator = nullptr; 
- }+    }
 } }
  
 Laptop::​~Laptop() Laptop::​~Laptop()
 { {
- if (producator != nullptr) +    ​if (producator != nullptr) 
-+    
- delete[] producator;​ +        delete[] producator;​ 
- }+    }
 } }
  
 float Laptop::​getPret() const float Laptop::​getPret() const
 { {
- return pret;+    ​return pret;
 } }
  
 char* Laptop::​getProducator() const char* Laptop::​getProducator() const
 { {
- return producator;+    ​return producator;
 } }
 </​code>​ </​code>​
Line 140: Line 140:
 SmartPhone::​SmartPhone() SmartPhone::​SmartPhone()
 { {
- pret = 0.0f; +    ​pret = 0.0f; 
- producator = nullptr;+    producator = nullptr;
 } }
  
 SmartPhone::​SmartPhone(const float& pret, const char* producator) SmartPhone::​SmartPhone(const float& pret, const char* producator)
 { {
- this->​pret = pret;+    ​this->​pret = pret;
  
- if (producator != nullptr) +    ​if (producator != nullptr) 
-+    
- this->​producator = new char[strlen(producator) + 1]; +        this->​producator = new char[strlen(producator) + 1]; 
- strcpy(this->​producator,​ producator);​ +        strcpy(this->​producator,​ producator);​ 
-+    
- else +    else 
-+    
- this->​producator = nullptr; +        this->​producator = nullptr; 
- }+    }
 } }
  
 SmartPhone::​~SmartPhone() SmartPhone::​~SmartPhone()
 { {
- if (producator != nullptr) +    ​if (producator != nullptr) 
-+    
- delete[] producator;​ +        delete[] producator;​ 
- }+    }
 } }
  
 float SmartPhone::​getPret() const float SmartPhone::​getPret() const
 { {
- return pret;+    ​return pret;
 } }
  
 char* SmartPhone::​getProducator() const char* SmartPhone::​getProducator() const
 { {
- return producator;+    ​return producator;
 } }
 </​code>​ </​code>​
Line 186: Line 186:
 int main() int main()
 { {
- int nrProduse = 5; +    ​int nrProduse = 5; 
- ProdusElectronic** produse = new ProdusElectronic * [nrProduse];​ // vector de obiecte neomogene+    ProdusElectronic** produse = new ProdusElectronic * [nrProduse];​ // vector de obiecte neomogene
  
- produse[0] = new Laptop(5499.99f,​ "​HP"​);​ // late binding +    ​produse[0] = new Laptop(5499.99f,​ "​HP"​);​ // late binding 
- produse[1] = new SmartPhone(2499.99f,​ "​Motorola"​);​ +    produse[1] = new SmartPhone(2499.99f,​ "​Motorola"​);​ 
- produse[2] = new Laptop(3000.0f,​ "​Asus"​);​ +    produse[2] = new Laptop(3000.0f,​ "​Asus"​);​ 
- produse[3] = new Laptop(7999.99f,​ "​Lenovo"​);​ +    produse[3] = new Laptop(7999.99f,​ "​Lenovo"​);​ 
- produse[4] = new SmartPhone(3999.99f,​ "​Apple"​);​+    produse[4] = new SmartPhone(3999.99f,​ "​Apple"​);​
  
- for (int i = 0; i < nrProduse; i++) +    ​for (int i = 0; i < nrProduse; i++) 
-+    
- std::cout << "​Pretul produsului este: " << produse[i]->​getPret() << '​\n';​ +        std::cout << "​Pretul produsului este: " << produse[i]->​getPret() << '​\n';​ 
- std::cout << "​Numele producatorului este: " << produse[i]->​getProducator() << "​\n\n";​ +        std::cout << "​Numele producatorului este: " << produse[i]->​getProducator() << "​\n\n";​ 
- }+    }
  
- return 0;+    ​return 0;
 } }
 </​code>​ </​code>​
Line 213: Line 213:
 int main() int main()
 { {
- int nrProduse = 5; +    ​int nrProduse = 5; 
- ProdusElectronic** produse = new ProdusElectronic * [nrProduse];​+    ProdusElectronic** produse = new ProdusElectronic * [nrProduse];​
  
- produse[0] = new Laptop(5499.99f,​ "​HP"​);​ // late binding +    ​produse[0] = new Laptop(5499.99f,​ "​HP"​);​ // late binding 
- produse[1] = new SmartPhone(2499.99f,​ "​Motorola"​);​ +    produse[1] = new SmartPhone(2499.99f,​ "​Motorola"​);​ 
- produse[2] = new Laptop(3000.0f,​ "​Asus"​);​ +    produse[2] = new Laptop(3000.0f,​ "​Asus"​);​ 
- produse[3] = new Laptop(7999.99f,​ "​Lenovo"​);​ +    produse[3] = new Laptop(7999.99f,​ "​Lenovo"​);​ 
- produse[4] = new SmartPhone(3999.99f,​ "​Apple"​);​+    produse[4] = new SmartPhone(3999.99f,​ "​Apple"​);​
  
- for (int i = 0; i < nrProduse; i++) +    ​for (int i = 0; i < nrProduse; i++) 
-+    
- std::cout << "​Pretul produsului este: " << produse[i]->​getPret() << '​\n';​ +        std::cout << "​Pretul produsului este: " << produse[i]->​getPret() << '​\n';​ 
- std::cout << "​Numele producatorului este: " << produse[i]->​getProducator() << "​\n\n";​ +        std::cout << "​Numele producatorului este: " << produse[i]->​getProducator() << "​\n\n";​ 
- }+    }
  
- for (int i = 0; i < nrProduse; i++) +    ​for (int i = 0; i < nrProduse; i++) 
-+    
- delete produse[i]; // eliberam fiecare slot din vector +        delete produse[i]; // eliberam fiecare slot din vector 
- }+    }
  
- delete[] produse; // stergem vectorul+    ​delete[] produse; // stergem vectorul
  
- return 0;+    ​return 0;
 } }
 </​code>​ </​code>​
Line 247: Line 247:
 În contextul exemplului prezentat anterior, ar fi foarte elegant să putem afișa elementele vectorului folosind **operatorul %%<<​%%**,​ ceea ce ar simplifica și uniformiza procesul de afișare. Totuși, o problemă fundamentală apare din faptul că acest operator poate fi **supraîncărcat**,​ dar nu și **suprascris**. ​ În contextul exemplului prezentat anterior, ar fi foarte elegant să putem afișa elementele vectorului folosind **operatorul %%<<​%%**,​ ceea ce ar simplifica și uniformiza procesul de afișare. Totuși, o problemă fundamentală apare din faptul că acest operator poate fi **supraîncărcat**,​ dar nu și **suprascris**. ​
  
-Prin urmare **operatorul %%<<​%%** nu poate fi declarat **virtual**,​ astfel încât să permită apelul unei implementări specifice **clasei derivate** atunci când este utilizat printr-un **pointer** sau o **referință** la **clasa de bază**. Soluția implică de obicei definirea unei metode virtuale în **clasa abstractă** și utilizarea acesteia în supraîncărcarea **operatorului %%<<​%%**. ​+Prin urmare **operatorul %%<<​%%** nu poate fi declarat **virtual**,​ astfel încât să permită apelul unei implementări specifice **clasei derivate** atunci când este utilizat printr-un **pointer** sau o **referință** la **clasa de bază**. Soluția implică de obicei definirea unei metode virtuale în **clasa abstractă** și utilizarea acesteia în supraîncărcarea **operatorului ​de afișare ​%%<<​%%**. ​
  
 Această abordare oferă o separare clară între logica specifică de afișare și mecanismul **operatorului %%<<​%%**,​ respectând în același timp principiile polimorfismului. Această abordare oferă o separare clară între logica specifică de afișare și mecanismul **operatorului %%<<​%%**,​ respectând în același timp principiile polimorfismului.
Line 258: Line 258:
 protected: protected:
  
- virtual void afisare(std::​ostream&​ out) const = 0; // va fi folosita pentru operatorul <<+    ​virtual void afisare(std::​ostream&​ out) const = 0; // va fi folosita pentru operatorul <<
  
 public: public:
  
- virtual ~ProdusElectronic() = 0;+    ​virtual ~ProdusElectronic() = 0;
  
- virtual float getPret() const = 0; +    ​virtual float getPret() const = 0; 
- virtual char* getProducator() const = 0;+    virtual char* getProducator() const = 0;
  
- friend std::​ostream&​ operator<<​(std::​ostream&​ out, const ProdusElectronic* const& produsElectronic);​+    ​friend std::​ostream&​ operator<<​(std::​ostream&​ out, const ProdusElectronic* const& produsElectronic);​
 }; };
 </​code>​ </​code>​
Line 276: Line 276:
 std::​ostream&​ operator<<​(std::​ostream&​ out, const ProdusElectronic* const& produsElectronic) std::​ostream&​ operator<<​(std::​ostream&​ out, const ProdusElectronic* const& produsElectronic)
 { {
- produsElectronic->​afisare(out);​ // ne folosim de late binding +    ​produsElectronic->​afisare(out);​ // ne folosim de late binding 
- return out;+    return out;
 } }
 </​code>​ </​code>​
Line 286: Line 286:
 class Laptop : public ProdusElectronic class Laptop : public ProdusElectronic
 { {
- float pret; +    ​float pret; 
- char* producator;+    char* producator;
  
 protected: protected:
  
- void afisare(std::​ostream&​ out) const override;+    ​void afisare(std::​ostream&​ out) const override;
  
 public: public:
  
- Laptop(); +    ​Laptop(); 
- Laptop(const float& pret, const char* producator);​ +    Laptop(const float& pret, const char* producator);​ 
- ~Laptop();+    ~Laptop();
  
- float getPret() const override; +    ​float getPret() const override; 
- char* getProducator() const override;+    char* getProducator() const override;
 }; };
 </​code>​ </​code>​
Line 307: Line 307:
 class SmartPhone : public ProdusElectronic class SmartPhone : public ProdusElectronic
 { {
- float pret; +    ​float pret; 
- char* producator;+    char* producator;
  
 protected: protected:
  
- void afisare(std::​ostream&​ out) const override;+    ​void afisare(std::​ostream&​ out) const override;
  
 public: public:
  
- SmartPhone();​ +    ​SmartPhone();​ 
- SmartPhone(const float& pret, const char* producator);​ +    SmartPhone(const float& pret, const char* producator);​ 
- ~SmartPhone();​+    ~SmartPhone();​
  
- float getPret() const override; +    ​float getPret() const override; 
- char* getProducator() const override;+    char* getProducator() const override;
 }; };
 </​code>​ </​code>​
Line 330: Line 330:
 void Laptop::​afisare(std::​ostream&​ out) const void Laptop::​afisare(std::​ostream&​ out) const
 { {
- out << "​Pretul laptopului este: " << pret << '​\n';​ +    ​out << "​Pretul laptopului este: " << pret << '​\n';​ 
- out << "​Numele producatorului de laptopuri este: ";+    out << "​Numele producatorului de laptopuri este: ";
  
- if (producator != nullptr) +    ​if (producator != nullptr) 
-+    
- out << producator << '​\n';​ +        out << producator << '​\n';​ 
-+    
- else +    else 
-+    
- out << "​N/​A\n";​ +        out << "​N/​A\n";​ 
- }+    }
 } }
 </​code>​ </​code>​
Line 347: Line 347:
 void SmartPhone::​afisare(std::​ostream&​ out) const void SmartPhone::​afisare(std::​ostream&​ out) const
 { {
- out << "​Pretul smartphone-ului este: " << pret << '​\n';​ +    ​out << "​Pretul smartphone-ului este: " << pret << '​\n';​ 
- out << "​Numele producatorului de smartphone-uri este: ";+    out << "​Numele producatorului de smartphone-uri este: ";
  
- if (producator != nullptr) +    ​if (producator != nullptr) 
-+    
- out << producator << '​\n';​ +        out << producator << '​\n';​ 
-+    
- else +    else 
-+    
- out << "​N/​A\n";​ +        out << "​N/​A\n";​ 
- }+    }
 } }
 </​code>​ </​code>​
Line 369: Line 369:
 int main() int main()
 { {
- int nrProduse = 5; +    ​int nrProduse = 5; 
- ProdusElectronic** produse = new ProdusElectronic * [nrProduse];​+    ProdusElectronic** produse = new ProdusElectronic * [nrProduse];​
  
- produse[0] = new Laptop(5499.99f,​ "​HP"​);​ +    ​produse[0] = new Laptop(5499.99f,​ "​HP"​);​ 
- produse[1] = new SmartPhone(2499.99f,​ "​Motorola"​);​ +    produse[1] = new SmartPhone(2499.99f,​ "​Motorola"​);​ 
- produse[2] = new Laptop(3000.0f,​ "​Asus"​);​ +    produse[2] = new Laptop(3000.0f,​ "​Asus"​);​ 
- produse[3] = new Laptop(7999.99f,​ "​Lenovo"​);​ +    produse[3] = new Laptop(7999.99f,​ "​Lenovo"​);​ 
- produse[4] = new SmartPhone(3999.99f,​ "​Apple"​);​+    produse[4] = new SmartPhone(3999.99f,​ "​Apple"​);​
  
- for (int i = 0; i < nrProduse; i++) +    ​for (int i = 0; i < nrProduse; i++) 
-+    
- std::cout << produse[i] << '​\n';​ // se foloseste operatorul << definit in interfata ProdusElectronic +        std::cout << produse[i] << '​\n';​ // se foloseste operatorul << definit in interfata ProdusElectronic 
- }+    }
  
- for (int i = 0; i < nrProduse; i++) +    ​for (int i = 0; i < nrProduse; i++) 
-+    
- delete produse[i];​ +        delete produse[i];​ 
- }+    }
  
- delete[] produse;+    ​delete[] produse;
  
- return 0;+    ​return 0;
 } }
 </​code>​ </​code>​
Line 396: Line 396:
 <note tip>În mod similar, procedăm și pentru ceilalți operatori, indiferent dacă sunt supraîncărcați ca **funcții membre** sau ca **funcții friend**. Acești operatori vor fi supraîncărcați **exclusiv** în **clasa de bază**, iar comportamentul lor specific poate fi ulterior personalizat în **clasele derivate** prin intermediul **suprascrierii**. ​ <note tip>În mod similar, procedăm și pentru ceilalți operatori, indiferent dacă sunt supraîncărcați ca **funcții membre** sau ca **funcții friend**. Acești operatori vor fi supraîncărcați **exclusiv** în **clasa de bază**, iar comportamentul lor specific poate fi ulterior personalizat în **clasele derivate** prin intermediul **suprascrierii**. ​
  
-Acest lucru se realizează prin definirea unor **funcții ​virtual pure** în clasa de bază, care stabilesc comportamentul operatorului respectiv în **subclase**. Clasele derivate vor implementa aceste **funcții ​virtuale**, asigurând astfel logica specifică operatorului în funcție de cerințele fiecărei clase. Această abordare permite un design flexibil și robust, bazat pe mecanismul de **run time polymorphism**.</​note>​+Acest lucru se realizează prin definirea unor **metode ​virtual pure** în clasa de bază, care stabilesc comportamentul operatorului respectiv în **subclase**. Clasele derivate vor implementa aceste **metode ​virtuale**, asigurând astfel logica specifică operatorului în funcție de cerințele fiecărei clase. Această abordare permite un design flexibil și robust, bazat pe mecanismul de **run time polymorphism**.</​note>​ 
 ==== Concluzii ==== ==== Concluzii ====
  
poo-is-ab/laboratoare/10.1758647673.txt.gz · Last modified: 2025/09/23 20:14 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