This shows you the differences between two versions of the page.
poo-is-ab:laboratoare:04 [2024/10/23 21:20] razvan.cristea0106 [Operatorii limbajului C++] |
poo-is-ab:laboratoare:04 [2025/01/19 22:28] (current) razvan.cristea0106 |
||
---|---|---|---|
Line 31: | Line 31: | ||
**Operatorul Ternar**: există un **singur** operator ternar în C++, cunoscut sub numele de **operator condițional (?:)**. Acesta utilizează **trei** operanzi și este folosit pentru a evalua o condiție și a alege între două valori, în funcție de rezultatul acelei condiții. | **Operatorul Ternar**: există un **singur** operator ternar în C++, cunoscut sub numele de **operator condițional (?:)**. Acesta utilizează **trei** operanzi și este folosit pentru a evalua o condiție și a alege între două valori, în funcție de rezultatul acelei condiții. | ||
- | În continuare vom prezenta un tabel cu operatorii din C++ unde vom vedea atât simbolurile cât și modul de asociere al acestora. | + | În continuare vom prezenta un tabel cu operatorii existenți în limbajul C++ pentru a putea vedea atât simbolurile cât și modul de asociere (aplicare) al acestora. |
^ Categoria de operatori ^ Simbolurile operatorilor ^ Mod de asociere (aplicare) ^ | ^ Categoria de operatori ^ Simbolurile operatorilor ^ Mod de asociere (aplicare) ^ | ||
Line 120: | Line 120: | ||
În mod evident puteam declara și implementa o metodă simplă de afișare în loc să optăm pentru o funcție **friend**. Trebuie însă menționat faptul că este doar un exemplu didactic pentru a putea înțelege cum putem folosi funcțiile **friend** în limbajul C++. | În mod evident puteam declara și implementa o metodă simplă de afișare în loc să optăm pentru o funcție **friend**. Trebuie însă menționat faptul că este doar un exemplu didactic pentru a putea înțelege cum putem folosi funcțiile **friend** în limbajul C++. | ||
- | <note warning>Deși sunt declarate în interiorul clasei funcțiile **friend** se numesc **funcții** și **nu metode** datorită faptului că nu primesc **pointerul this** în lista de parametri. Cuvântul cheie **friend** se utilizează **doar** la declararea funcției pentru a înștința compilatorul că este vorba despre o **funcție** și **nu** despre o **metodă**, iar implementarea acesteia este **identică** cu a unei **funcții clasice din C++**.</note> | + | <note warning>Deși sunt declarate în interiorul clasei **funcțiile friend** se numesc **funcții** și **nu metode** datorită faptului că **nu** primesc **pointerul this** în lista de parametri. Cuvântul cheie **friend** se utilizează **doar** la declararea funcției pentru a înștința compilatorul că este vorba despre o **funcție** și **nu** despre o **metodă**, iar implementarea acesteia este **identică** cu a unei **funcții clasice din C++**.</note> |
Vom folosi foarte mult acest tip de funcții după cum vom vedea în cele ce urmează la supraîncărcarea operatorilor limbajului C++. | Vom folosi foarte mult acest tip de funcții după cum vom vedea în cele ce urmează la supraîncărcarea operatorilor limbajului C++. | ||
Line 245: | Line 245: | ||
</code> | </code> | ||
- | <note important>Se poate observa ca la **forma postfixată** avem un parametru de care **nu** ne folosim. Acel parametru este **doar** pentru a asigura **polimorfismul**, compilatorul facând distincția între cele două variante de operator de incrementare.</note> | + | <note important>Se poate observa ca la **forma postfixată** avem un parametru de care **nu** ne folosim. Acel parametru este **doar** pentru a asigura **polimorfismul**, compilatorul făcând distincția între cele două variante de operator de incrementare.</note> |
Pentru **operatorul de decrementare** se aplică aceleași **exact** aceeași pași, încercați să îl implementați voi pentru a putea înțelege mai bine cum funcționează conceptul de **overloading**. | Pentru **operatorul de decrementare** se aplică aceleași **exact** aceeași pași, încercați să îl implementați voi pentru a putea înțelege mai bine cum funcționează conceptul de **overloading**. | ||
Line 299: | Line 299: | ||
== Supraîncărcarea operatorilor == și != == | == Supraîncărcarea operatorilor == și != == | ||
- | **Operatorul %%==%%** este folosit pentru a testa egaliatetea dintre doi operanizi, deci prin urmare trebuie să returneze o valoare de adevăr (**true** sau **false**). Îl supraîncârcăm ca funcție membră, deoarece avem deja un parametru existent, și anume **pointerul this**, la care mai adăugăm un alt parametru care reprezintă **obiectul cu care facem comparația**. | + | **Operatorul %%==%%** este folosit pentru a testa egaliatetea dintre doi operanzi, deci prin urmare trebuie să returneze o valoare de adevăr (**true** sau **false**). Îl supraîncârcăm ca funcție membră, deoarece avem deja un parametru existent, și anume **pointerul this**, la care mai adăugăm un alt parametru care reprezintă **obiectul cu care facem comparația**. |
Același lucru putem spune și despre **operatorul %%!=%%**, numai că el face exact **opusul** a ceea ce face operatorul de testare a egalității între doi operanzi, adică verifică dacă valorile celor doi termeni sunt **diferite**. | Același lucru putem spune și despre **operatorul %%!=%%**, numai că el face exact **opusul** a ceea ce face operatorul de testare a egalității între doi operanzi, adică verifică dacă valorile celor doi termeni sunt **diferite**. | ||
Line 345: | Line 345: | ||
bool NrComplex::operator!=(const NrComplex& z) const | bool NrComplex::operator!=(const NrComplex& z) const | ||
{ | { | ||
- | return this->real != z.real && this->imaginar != z.imaginar; | + | return this->real != z.real || this->imaginar != z.imaginar; |
} | } | ||
</code> | </code> | ||
Line 565: | Line 565: | ||
Codul complet cu implementările operatorilor prezentați pentru clasa **NrComplex** poate fi descărcat de {{:poo-is-ab:laboratoare:complex_overloading.zip|aici}}. | Codul complet cu implementările operatorilor prezentați pentru clasa **NrComplex** poate fi descărcat de {{:poo-is-ab:laboratoare:complex_overloading.zip|aici}}. | ||
- | <note warning>În limbajul C++ **nu** este permisă supraîncărcarea operatorilor următori: | + | <note warning>În limbajul C++ **nu** este permisă supraîncărcarea următorilor operatori: |
* de rezoluție **"::"** | * de rezoluție **"::"** | ||
* de acces la membrii unei clase/structuri **"."** | * de acces la membrii unei clase/structuri **"."** | ||
Line 576: | Line 576: | ||
==== Concluzii ==== | ==== Concluzii ==== | ||
- | În cadrul acestui laborator, am descoperit **importanța supraîncărcării operatorilor** într-o clasă și modul în care acest proces ne permite să efectuăm diverse operații într-un mod **intuitiv**, la fel cum procedăm și cu **tipurile de date standard (int, float, char,...)**. Prin **supraîncărcarea operatorilor**, am reușit să **îmbunătățim lizibilitatea și ușurința** în utilizarea claselor personalizate, oferind posibilitatea de a efectua **operații** cum ar fi **adunarea**, **scăderea** sau **compararea** obiectelor de tipul definit de noi. | + | În cadrul acestui laborator, am descoperit **importanța supraîncărcării operatorilor** într-o clasă și modul în care acest proces ne permite să efectuăm diverse operații într-un mod **intuitiv**, la fel cum procedăm și cu **tipurile de date standard** (**int**, **float**, **char**,...). Prin **supraîncărcarea operatorilor**, am reușit să **îmbunătățim lizibilitatea și ușurința** în utilizarea claselor personalizate, oferind posibilitatea de a efectua **operații** cum ar fi **adunarea**, **scăderea** sau **compararea** obiectelor de tipul definit de noi. |
- | Am înțeles, de asemenea, când este necesar să supraîncărcăm un operator ca **funcție membră** a unei clase și când este mai potrivit să îl supraîncărcăm ca **funcție friend**. Operatorii care au nevoie de **acces direct** la membrii clasei, cum ar fi **operatorii unari** sau **operatorul de asignare**, sunt adesea implementați ca **funcții membre**. În schimb, operatorii care implică obiecte de **diferite tipuri** (de exemplu, un obiect al clasei noastre și un tip fundamental precum **int** sau **double**) pot fi implementați mai eficient ca **funcții friend**, pentru a permite accesul din exterior la membri privați **fără** a compromite **încapsularea**. | + | Am înțeles, de asemenea, când este necesar să **supraîncărcăm** un operator ca **funcție membră** a unei clase și când este mai potrivit să îl supraîncărcăm ca **funcție friend**. Operatorii care au nevoie de **acces direct** la membrii clasei, cum ar fi **operatorii unari** sau **operatorul de asignare**, sunt adesea implementați ca **funcții membre**. În schimb, operatorii care implică obiecte de **diferite tipuri** (de exemplu, un obiect al clasei noastre și un tip fundamental precum **int** sau **double**) pot fi implementați mai eficient ca **funcții friend**, pentru a permite accesul din exterior la membri privați **fără** a compromite **încapsularea datelor clasei**. |