This shows you the differences between two versions of the page.
poo-is-ab:laboratoare:02 [2025/09/23 22:22] razvan.cristea0106 [Diferențe C/C++] |
poo-is-ab:laboratoare:02 [2025/10/04 18:30] (current) razvan.cristea0106 [Concluzii] |
||
---|---|---|---|
Line 12: | Line 12: | ||
==== Introducere ==== | ==== Introducere ==== | ||
- | În cadrul acestui laborator vom evidenția principalele diferențe dintre limbajele C și C++. Vom analiza, prin exemple simple, modul în care C++ extinde caracteristicile limbajului C și vom pune bazele unei înțelegeri mai profunde a acestuia. Astfel, vom avea un punct de plecare solid pentru paradigma **Orientată Obiect (OO)** pe care o vom studia începând cu laboratorul următor. | + | În cadrul acestui laborator vom evidenția principalele diferențe dintre limbajele C și C++. Vom analiza, prin exemple simple, modul în care C++ extinde caracteristicile limbajului C și vom pune bazele unei înțelegeri mai profunde a acestuia. Astfel, vom avea un punct de plecare solid pentru paradigma **Orientată Obiect (OO)** pe care o vom studia începând cu laboratorul următor. Pentru a înțelege diferențele dintre cele două limbaje mai întâi ar trebui să știm care sunt asemănările, iar pentru asta recomandăm citirea [[poo-is-ab:laboratoare:01| laboratorului 1]]. |
==== Diferențe C/C++ ==== | ==== Diferențe C/C++ ==== | ||
Line 27: | Line 27: | ||
int main() | int main() | ||
{ | { | ||
- | int x; | + | int x; |
- | printf("Introduceti un numar: "); | + | printf("Introduceti un numar: "); |
- | scanf("%d", &x); | + | scanf("%d", &x); |
- | printf("Numarul introdus de utilizator este: %d\n", x); | + | printf("Numarul introdus de utilizator este: %d\n", x); |
- | return 0; | + | return 0; |
} | } | ||
</code> | </code> | ||
Line 45: | Line 45: | ||
int main() | int main() | ||
{ | { | ||
- | int x; | + | int x; |
- | std::cout << "Introduceti un numar: "; // cout vine de la console output | + | std::cout << "Introduceti un numar: "; // cout vine de la console output |
- | std::cin >> x; // cin vine de la console input | + | std::cin >> x; // cin vine de la console input |
- | std::cout << "Numarul introdus de utilizator este: " << x << '\n'; | + | std::cout << "Numarul introdus de utilizator este: " << x << '\n'; |
- | return 0; | + | return 0; |
} | } | ||
</code> | </code> | ||
<note>Este de menționat faptul ca în C++ și funcțiile **scanf** și **printf** se pot utiliza, dar ca și recomandare ar fi mai indicată utilizarea operatorilor de citire și afișare ai limbajului, deoarece sunt mai specializați pentru ceea ce vom învăța pe parcursul semestrului.</note> | <note>Este de menționat faptul ca în C++ și funcțiile **scanf** și **printf** se pot utiliza, dar ca și recomandare ar fi mai indicată utilizarea operatorilor de citire și afișare ai limbajului, deoarece sunt mai specializați pentru ceea ce vom învăța pe parcursul semestrului.</note> | ||
+ | |||
+ | == Citirea și scrierea datelor în fișiere == | ||
+ | |||
+ | În această secțiune vom prezenta modul de citire și scriere a datelor în fișierele text în limbajul C++. La fel ca în limbajul C aici avem posibilitatea să folosim funcțiile **fscanf** și **fprintf** însă se recomandă folosirea librăriei **fstream** care este specializată pentru lucrul cu fișiere. Dacă dorim să citim date dintr-un fișier vom volosi variabile de tipul **ifstream** (**input file stream**) iar pentru pentru scriere se utilizează tipul **ofstream** (**output file stream**). | ||
+ | |||
+ | Mai jos este prezentat un exemplu simplu de folosire a datelor de tip **ifstream** și **ofstream**. | ||
+ | |||
+ | <code cpp> | ||
+ | #include <fstream> | ||
+ | #include <iostream> | ||
+ | |||
+ | void scrieInFisier(const char* numeFisier) | ||
+ | { | ||
+ | std::ofstream outFile(numeFisier); | ||
+ | |||
+ | if (!outFile) // verificam daca fisierul a fost deschis | ||
+ | { | ||
+ | std::cerr << "Eroare la deschiderea fisierului pentru scriere!\n"; | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | outFile << "Ana" << " " << 20 << " " << 9.5 << '\n'; | ||
+ | outFile << "Ion" << " " << 22 << " " << 8.75 << '\n'; | ||
+ | outFile << "Maria" << " " << 19 << " " << 10.0 << '\n'; | ||
+ | |||
+ | outFile.close(); | ||
+ | } | ||
+ | |||
+ | void citesteDinFisier(const char* numeFisier) | ||
+ | { | ||
+ | std::ifstream inFile(numeFisier); | ||
+ | |||
+ | if (!inFile) // verificam daca fisierul a fost deschis | ||
+ | { | ||
+ | std::cerr << "Eroare la deschiderea fisierului pentru citire!\n"; | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | int varsta; | ||
+ | double nota; | ||
+ | char nume[50]; | ||
+ | |||
+ | std::cout << "Inregistrarile citite din fisier se pot observa mai jos\n\n"; | ||
+ | |||
+ | while (inFile >> nume >> varsta >> nota) // citim pana cand nu mai avem date | ||
+ | { | ||
+ | std::cout << "Nume: " << nume | ||
+ | << ", Varsta: " << varsta | ||
+ | << ", Nota: " << nota << '\n'; | ||
+ | } | ||
+ | |||
+ | inFile.close(); | ||
+ | } | ||
+ | |||
+ | int main() | ||
+ | { | ||
+ | const char* denumireFisier = "studenti.txt"; | ||
+ | |||
+ | scrieInFisier(denumireFisier); | ||
+ | citesteDinFisier(denumireFisier); | ||
+ | |||
+ | return 0; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | Iar în consolă output-ul arată ca mai jos. | ||
+ | |||
+ | <file> | ||
+ | Inregistrarile citite din fisier se pot observa mai jos | ||
+ | |||
+ | Nume: Ana, Varsta: 20, Nota: 9.5 | ||
+ | Nume: Ion, Varsta: 22, Nota: 8.75 | ||
+ | Nume: Maria, Varsta: 19, Nota: 10 | ||
+ | </file> | ||
+ | |||
+ | <note tip>În mod normal nu este necesară apelarea funcției **close** pentru a închide fluxurile de **citire** și de **scriere** în fișier, deoarece acestea au un **mecanism automat** de închidere atunci când se termină execuția unei funcții. În cazul exemplului de mai sus nu este necesară apelarea funcției **close** deoarece variabilele de tip **ifstream** și **ofstream** sunt variabile locale în funcțiile în care apar. Dacă am fi scris tot codul în funcția **main** atunci apelarea funcției **close** devenea obligatorie după ce terminam partea de scriere în fișier.</note> | ||
=== Alocarea dinamică a memoriei === | === Alocarea dinamică a memoriei === | ||
Line 71: | Line 147: | ||
int main() | int main() | ||
{ | { | ||
- | int* ptr1 = (int*)malloc(sizeof(int)); | + | int* ptr1 = (int*)malloc(sizeof(int)); |
- | *ptr1 = 5; | + | *ptr1 = 5; |
- | // sau folosind calloc | + | // sau folosind calloc |
- | int* ptr2 = (int*)calloc(1, sizeof(int)); | + | int* ptr2 = (int*)calloc(1, sizeof(int)); |
- | std::cout << *ptr2 << '\n'; | + | std::cout << *ptr2 << '\n'; |
- | *ptr2 = *ptr1; | + | *ptr2 = *ptr1; |
- | std::cout << *ptr1 << '\n'; | + | std::cout << *ptr1 << '\n'; |
- | std::cout << *ptr2 << '\n'; | + | std::cout << *ptr2 << '\n'; |
- | free(ptr1); | + | free(ptr1); |
- | free(ptr2); | + | free(ptr2); |
- | return 0; | + | return 0; |
} | } | ||
</code> | </code> | ||
Line 95: | Line 171: | ||
<code cpp> | <code cpp> | ||
+ | #include <iostream> | ||
+ | |||
int main() | int main() | ||
{ | { | ||
- | int nrElemente = 5; | + | int nrElemente = 5; |
- | int* vector = (int*)malloc(nrElemente * sizeof(int)); | + | int* vector = (int*)malloc(nrElemente * sizeof(int)); |
- | vector[0] = 3; | + | vector[0] = 3; |
- | vector[1] = 2; | + | vector[1] = 2; |
- | vector[2] = -2; | + | vector[2] = -2; |
- | vector[3] = 10; | + | vector[3] = 10; |
- | vector[4] = 8; | + | vector[4] = 8; |
- | std::cout << "Vectorul alocat dinamic este: "; | + | std::cout << "Vectorul alocat dinamic este: "; |
- | for (int i = 0; i < nrElemente; i++) | + | for (int i = 0; i < nrElemente; i++) |
- | { | + | { |
- | std::cout << vector[i] << ' '; | + | std::cout << vector[i] << ' '; |
- | } | + | } |
- | free(vector); | + | free(vector); |
- | return 0; | + | return 0; |
} | } | ||
</code> | </code> | ||
Line 122: | Line 200: | ||
<code cpp> | <code cpp> | ||
+ | #include <iostream> | ||
+ | |||
int main() | int main() | ||
{ | { | ||
- | int nrElemente = 5; | + | int nrElemente = 5; |
- | int* vector = (int*)malloc(nrElemente * sizeof(int)); | + | int* vector = (int*)malloc(nrElemente * sizeof(int)); |
- | vector[0] = 3; | + | vector[0] = 3; |
- | vector[1] = 2; | + | vector[1] = 2; |
- | vector[2] = -2; | + | vector[2] = -2; |
- | vector[3] = 10; | + | vector[3] = 10; |
- | vector[4] = 8; | + | vector[4] = 8; |
- | std::cout << "Vectorul alocat dinamic este: "; | + | std::cout << "Vectorul alocat dinamic este: "; |
- | for (int i = 0; i < nrElemente; i++) | + | for (int i = 0; i < nrElemente; i++) |
- | { | + | { |
- | std::cout << vector[i] << ' '; | + | std::cout << vector[i] << ' '; |
- | } | + | } |
- | nrElemente = 8; | + | nrElemente = 8; |
- | vector = (int*)realloc(vector, nrElemente * sizeof(int)); | + | vector = (int*)realloc(vector, nrElemente * sizeof(int)); |
- | vector[5] = 15; | + | vector[5] = 15; |
- | vector[6] = 20; | + | vector[6] = 20; |
- | vector[7] = 25; | + | vector[7] = 25; |
- | std::cout << "\nVectorul realocat dinamic este: "; | + | std::cout << "\nVectorul realocat dinamic este: "; |
- | for (int i = 0; i < nrElemente; i++) | + | for (int i = 0; i < nrElemente; i++) |
- | { | + | { |
- | std::cout << vector[i] << ' '; | + | std::cout << vector[i] << ' '; |
- | } | + | } |
- | free(vector); | + | free(vector); |
- | return 0; | + | return 0; |
} | } | ||
</code> | </code> | ||
Line 174: | Line 254: | ||
int main() | int main() | ||
{ | { | ||
- | int* ptr1 = new int; // alocare dinamica fara initializare, compilatorul va atribui o valoare in mod aleator | + | int* ptr1 = new int; // alocare dinamica fara initializare, compilatorul va atribui o valoare in mod aleator |
- | int* ptr2 = new int(10); // alocare dinamica cu initializare | + | int* ptr2 = new int(10); // alocare dinamica cu initializare |
- | std::cout << *ptr1 << '\n'; | + | std::cout << *ptr1 << '\n'; |
- | std::cout << *ptr2 << '\n'; | + | std::cout << *ptr2 << '\n'; |
- | /*delete ptr1, ptr2; // desi nu da eroare de compilare va elibera doar spatiul pentru ptr1, nu se recomanda aceasta scriere pentru ca va genera memory leak-uri usor*/ | + | /*delete ptr1, ptr2; // desi nu da eroare de compilare va elibera doar spatiul pentru ptr1, nu se recomanda aceasta scriere pentru ca va genera memory leak-uri usor*/ |
- | delete ptr1; | + | delete ptr1; |
- | delete ptr2; | + | delete ptr2; |
- | return 0; | + | return 0; |
} | } | ||
</code> | </code> | ||
Line 200: | Line 280: | ||
int main() | int main() | ||
{ | { | ||
- | int nrElemente = 5; | + | int nrElemente = 5; |
- | int* vector = new int[nrElemente]; // se folosesc [] pentru a anunta compilatorul ca vrem sa alocam spatiu pentru un bloc de memorie continuu | + | int* vector = new int[nrElemente]; // se folosesc [] pentru a anunta compilatorul ca vrem sa alocam spatiu pentru un bloc de memorie continuu |
- | for (int i = 0; i < nrElemente; i++) | + | for (int i = 0; i < nrElemente; i++) |
- | { | + | { |
- | std::cout << "vector[" << i << "] = "; | + | std::cout << "vector[" << i << "] = "; |
- | std::cin >> vector[i]; | + | std::cin >> vector[i]; |
- | } | + | } |
- | std::cout << "\nElementele vectorului alocat sunt: "; | + | std::cout << "\nElementele vectorului alocat sunt: "; |
- | for (int i = 0; i < nrElemente; i++) | + | for (int i = 0; i < nrElemente; i++) |
- | { | + | { |
- | std::cout << vector[i] << ' '; | + | std::cout << vector[i] << ' '; |
- | } | + | } |
- | delete[] vector; // se folosesc [] pentru a anunta compilatorul ca ne dorim sa eliberam memoria unui bloc contiguu | + | delete[] vector; // se folosesc [] pentru a anunta compilatorul ca ne dorim sa eliberam memoria unui bloc contiguu |
- | return 0; | + | return 0; |
} | } | ||
</code> | </code> | ||
Line 229: | Line 309: | ||
int main() | int main() | ||
{ | { | ||
- | int nrElemente = 6; | + | int nrElemente = 6; |
- | int* vector = new int[nrElemente]; | + | int* vector = new int[nrElemente]; |
- | for (int i = 0; i < nrElemente; i++) | + | for (int i = 0; i < nrElemente; i++) |
- | { | + | { |
- | std::cout << "vector[" << i << "] = "; | + | std::cout << "vector[" << i << "] = "; |
- | std::cin >> vector[i]; | + | std::cin >> vector[i]; |
- | } | + | } |
- | std::cout << "\nElementele vectorului alocat sunt: "; | + | std::cout << "\nElementele vectorului alocat sunt: "; |
- | for (int i = 0; i < nrElemente; i++) | + | for (int i = 0; i < nrElemente; i++) |
- | { | + | { |
- | std::cout << vector[i] << ' '; | + | std::cout << vector[i] << ' '; |
- | } | + | } |
- | delete[] vector; | + | delete[] vector; |
- | nrElemente = 3; | + | nrElemente = 3; |
- | vector = new int[nrElemente]; | + | vector = new int[nrElemente]; |
- | std::cout << "\n\n===================================================\n\n"; | + | std::cout << "\n\n===================================================\n\n"; |
- | for (int i = 0; i < nrElemente; i++) | + | for (int i = 0; i < nrElemente; i++) |
- | { | + | { |
- | std::cout << "vector[" << i << "] = "; | + | std::cout << "vector[" << i << "] = "; |
- | std::cin >> vector[i]; | + | std::cin >> vector[i]; |
- | } | + | } |
- | std::cout << "\nElementele vectorului realocat sunt: "; | + | std::cout << "\nElementele vectorului realocat sunt: "; |
- | for (int i = 0; i < nrElemente; i++) | + | for (int i = 0; i < nrElemente; i++) |
- | { | + | { |
- | std::cout << vector[i] << ' '; | + | std::cout << vector[i] << ' '; |
- | } | + | } |
- | std::cout << '\n'; | + | std::cout << '\n'; |
- | delete[] vector; | + | delete[] vector; |
- | return 0; | + | return 0; |
} | } | ||
</code> | </code> | ||
Line 290: | Line 370: | ||
int main() | int main() | ||
{ | { | ||
- | int x = 10; | + | int x = 10; |
- | int& ref = x; | + | int& ref = x; |
- | ref = 16; | + | ref = 16; |
- | std::cout << x << '\n'; // x devine 16 deoarece ref este un alias pentru el | + | std::cout << x << '\n'; // x devine 16 deoarece ref este un alias pentru el |
- | x = 20; | + | x = 20; |
- | std::cout << ref << '\n'; // ref este 20 datorita faptului ca se refera la x | + | std::cout << ref << '\n'; // ref este 20 datorita faptului ca se refera la x |
- | int y = 0; | + | int y = 0; |
- | ref = y; // poate parea schimbarea referintei dar in realitate este doar atribuirea valorii 0 lui ref | + | ref = y; // poate parea schimbarea referintei dar in realitate este doar atribuirea valorii 0 lui ref |
- | std::cout << x << '\n'; // x este 0 din motive evidente | + | std::cout << x << '\n'; // x este 0 din motive evidente |
- | return 0; | + | return 0; |
} | } | ||
</code> | </code> | ||
Line 321: | Line 401: | ||
void alocareVector(int*& v, const int& dim) | void alocareVector(int*& v, const int& dim) | ||
{ | { | ||
- | v = new int[dim]; | + | v = new int[dim]; |
} | } | ||
void citireVector(int*& v, const int& dim) | void citireVector(int*& v, const int& dim) | ||
{ | { | ||
- | for (int i = 0; i < dim; i++) | + | for (int i = 0; i < dim; i++) |
- | { | + | { |
- | std::cout << "vector[" << i << "] = "; | + | std::cout << "vector[" << i << "] = "; |
- | std::cin >> v[i]; | + | std::cin >> v[i]; |
- | } | + | } |
} | } | ||
void afisareVector(const int* const& v, const int& dim) | void afisareVector(const int* const& v, const int& dim) | ||
{ | { | ||
- | std::cout << "Elementele vectorului alocat sunt: "; | + | std::cout << "Elementele vectorului alocat sunt: "; |
- | for (int i = 0; i < dim; i++) | + | for (int i = 0; i < dim; i++) |
- | { | + | { |
- | std::cout << v[i] << ' '; | + | std::cout << v[i] << ' '; |
- | } | + | } |
- | std::cout << '\n'; | + | std::cout << '\n'; |
} | } | ||
void dezalocareVector(int*& v) | void dezalocareVector(int*& v) | ||
{ | { | ||
- | if (v != nullptr) | + | if (v != nullptr) |
- | { | + | { |
- | delete[] v; | + | delete[] v; |
- | } | + | } |
} | } | ||
int main() | int main() | ||
{ | { | ||
- | int nrElemente = 5; | + | int nrElemente = 5; |
- | int* vector = nullptr; | + | int* vector = nullptr; |
- | alocareVector(vector, nrElemente); | + | alocareVector(vector, nrElemente); |
- | citireVector(vector, nrElemente); | + | citireVector(vector, nrElemente); |
- | afisareVector(vector, nrElemente); | + | afisareVector(vector, nrElemente); |
- | dezalocareVector(vector); | + | dezalocareVector(vector); |
- | return 0; | + | return 0; |
} | } | ||
</code> | </code> | ||
Line 373: | Line 453: | ||
Funcția afisareVector folosește referințe constante la pointeri (const int* const& v), pentru a garanta că atât adresa vectorului, cât și conținutul acestuia nu vor fi modificate în timpul afișării, menținând integritatea datelor. | Funcția afisareVector folosește referințe constante la pointeri (const int* const& v), pentru a garanta că atât adresa vectorului, cât și conținutul acestuia nu vor fi modificate în timpul afișării, menținând integritatea datelor. | ||
- | <note important>C++ introduce posibilitatea de a inițializa pointerii cu **nullptr**, care este specific doar pentru acest tip de date. Acesta funcționează similar cu **NULL**, dar cu un avantaj important: **nullptr** este un tip de date dedicat **pointerilor**, ceea ce previne atribuirea sa accidentală altor tipuri de variabile, cum se putea întâmpla cu **NULL** în C++. În C++, **NULL** este definit doar ca un **macro** care reprezintă valoarea 0 și poate fi atribuit chiar și variabilelor care nu sunt pointeri, lucru care poate duce la confuzii nedorite.</note> | + | <note important>C++ introduce posibilitatea de a inițializa pointerii cu **nullptr**, care este specific doar pentru acest tip de date. Acesta funcționează similar cu **NULL**, dar cu un avantaj important: **nullptr** este un tip de date dedicat **pointerilor**, ceea ce previne atribuirea sa accidentală altor tipuri de variabile. În C++, **NULL** este definit doar ca un **macro define** care reprezintă valoarea 0 și poate fi atribuit chiar și variabilelor care nu sunt de tip pointer, lucru care poate duce la confuzii nedorite.</note> |
<code cpp> | <code cpp> | ||
Line 380: | Line 460: | ||
int main() | int main() | ||
{ | { | ||
- | int x = NULL; // valid | + | int x = NULL; // valid |
- | int* ptr = NULL; // valid | + | int* ptr = NULL; // valid |
- | ptr = nullptr; // valid | + | ptr = nullptr; // valid |
- | x = nullptr; // eroare de compilare x nu este un pointer | + | x = nullptr; // eroare de compilare, x nu este un pointer |
- | return 0; | + | return 0; |
} | } | ||
</code> | </code> | ||
Line 392: | Line 472: | ||
=== Funcții cu același nume === | === Funcții cu același nume === | ||
- | În C++ avem avantajul de a declara funcții cu acelasi nume dar care să difere prin numărul și/sau tipul parametrilor. Această modalitate de declarare a funcțiilor este cunoscută în **Programarea Orientată Obiect** sub numele de **polimorfism** care înseamnă multe forme. Vom oferi mai multe detalii pe parcursul întregului semestru despre acest principiu al **POO**. | + | În C++ avem avantajul de a declara funcții, procedeu cunoscut sub numele de **supraîncărcare a funcțiilor**, cu **același nume** dar care să difere prin **numărul și/sau tipul parametrilor**. Această modalitate de declarare a funcțiilor este cunoscută în **Programarea Orientată Obiect** sub numele de **polimorfism**, care în limba greacă înseamnă **multe forme**. Vom oferi mai multe detalii pe parcursul întregului semestru despre acest principiu al **POO**. |
- | Să urmărim exemplul de cod de mai jos care ilustrează polimorfismul a trei funcții. | + | Să urmărim exemplul de cod de mai jos care ilustrează polimorfismul a patru funcții. |
+ | <code cpp> | ||
+ | #include <iostream> | ||
+ | int suma(int a, int b) | ||
+ | { | ||
+ | return a + b; | ||
+ | } | ||
+ | |||
+ | float suma(float a, float b) | ||
+ | { | ||
+ | return a + b; | ||
+ | } | ||
+ | |||
+ | float suma(float a, int b) | ||
+ | { | ||
+ | return a + b; | ||
+ | } | ||
+ | |||
+ | float suma(int a, float b) | ||
+ | { | ||
+ | return a + b; | ||
+ | } | ||
+ | |||
+ | int main() | ||
+ | { | ||
+ | std::cout << suma(2, 5) << '\n'; // prima functie denumita suma | ||
+ | std::cout << suma(2.5f, 5.5f) << '\n'; // a doua functie denumita suma | ||
+ | std::cout << suma(2.85f, 8) << '\n'; // a treia functie denumita suma | ||
+ | std::cout << suma(10, 8.5f) << '\n'; // // a patra functie denumita suma | ||
+ | |||
+ | return 0; | ||
+ | } | ||
+ | </code> | ||
- | <note tip>tip</note> | + | <note important>Trebuie subliniat faptul că **tipul de return** al unei funcții **nu** este luat în considerare în contextul polimorfismului prin supraîncărcare. Ceea ce definește **polimorfismul** în acest caz este exclusiv **semnătura funcției**, adică **numele împreună cu lista și tipurile parametrilor**. De aceea, două funcții care diferă doar prin tipul valorii returnate **nu** sunt considerate supraîncărcări valide. În schimb, diferențele în **numărul**, **tipul** sau chiar **ordinea** parametrilor constituie forme acceptate de **polimorfism**, așa cum se poate observa în cazul ultimelor două funcții din exemplul de mai sus.</note> |
==== Concluzii ==== | ==== Concluzii ==== | ||
- | În acest laborator, am explorat în detaliu diferențele fundamentale dintre clase și structuri, subliniind faptul că singura deosebire constă în specificatorul de acces implicit: la structuri, membrii sunt publici, iar la clase sunt privați. Totodată, am învățat cum să creăm obiecte și cum să le gestionăm proprietățile folosind constructori, precum și accesori prin intermediul getter-ilor și al setter-ilor. Acest lucru ne oferă un control mai fin asupra datelor și ne permite o manipulare clară și sigură a obiectelor într-un program care folosește conceptele **OOP**. Astfel, am dobândit o înțelegere mai bună a principiilor fundamentale ale **Programării Orientate Obiect**, principii pe care le vom aplica pe întregul parcurs al semestrului. | + | Prin parcurgerea acestui laborator, putem spune cu certitudine că limbajul C++ reprezintă o evoluție firească a limbajului C, adăugând numeroase concepte și mecanisme care ne fac munca de programatori mai simplă și mai expresivă. Am văzut că librăria **fstream**, alocarea dinamică realizată într-un mod simplificat, introducerea referințelor, posibilitatea de a supraîncărca funcții și suportul pentru **Programarea Orientată Obiect** diferențiază C++ de C și ne oferă un cadru mai flexibil pentru dezvoltarea aplicațiilor. Totuși, este important să reținem faptul că C++ rămâne compatibil cu C la nivel de bază, ceea ce îl face un limbaj versatil, potrivit atât pentru stilul **procedural**, cât și pentru cel **orientat pe obiecte**. |