Differences

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

Link to this comparison view

sd-ca:laboratoare:laborator-02 [2016/02/21 19:37]
radu.stochitoiu
sd-ca:laboratoare:laborator-02 [2016/02/21 19:51] (current)
radu.stochitoiu
Line 3: Line 3:
 ===== Obiective ===== ===== Obiective =====
  
-În urma parcurgerii acestui ​laborator ​studentul va: +În urma parcurgerii acestui ​articol ​studentul va: 
  
-  * înțelege conceptul de template +  * învăța ce înseamnă o clasă 
-  * înțelege conceptul de referințdin C++ +  * învăța ce înseamnă constructor / destructor 
-  * înțelege conceptul de read-only introdus prin identificatorul const+  * afla funcționalitățile claselor / funcțiilor prietene 
 +  * realiza supraîncărcarea operatorilor ​din C++ 
 +  * înțelege conceptul de copy constructor 
 +  * înțelege conceptul de rule of three
  
-  ​*Învățăce înseamnă ​constructor ​destructor+ 
 + 
 +==== Clase ==== 
 + 
 +Formal am făcut deja primii pași mai sus pentru a implementa o clasă în C++, utilizând keyword-ul //​struct//​. 
 + 
 +Totuși, ce înseamnă o clasă? Nu trebuie decât să ne gândim la ce am făcut mai sus: 
 +  ​*am definit un tip de date 
 +  *i-am adăugat atribute (am definit ce proprietăți îl caracterizează: partea reală și partea imaginară) 
 +  *i-am adăugat metode (am definit cum se comportă: inițializarea și conjugarea) 
 + 
 +Cu această adăugare menționată,​ putem să ne referim la ceea ce înseamnă ​o **clasă**, respectiv un **obiect**. 
 + 
 +Ne referim la o **clasă** ca fiind o amprentă (blueprint) sau descriere generală. 
 +Un **obiect** sau o **instanță a clasei** este o variabilă concretă ce se conformează descrierii clasei. 
 + 
 +Vom numi **clasă** tipul de date definit de //struct complex// sau //class complex// și **obiect** o instanțiere (o alocare dinamică sau locală) a tipului de date. 
 + 
 +Când discutăm despre tipul de date //complex// ne referim la clasă. 
 +Când discutăm despre variabila //number// ne referim la un obiect, o instanță a clasei. 
 + 
 +==== Keyword-ul "​class"​ vs. "​struct"​ ==== 
 + 
 +Și totuși, C++ adăugă keyword-ul //class//. Care este diferența între //class// și //​struct//?​ 
 +Iată cum definim complet clasa de mai sus, separând antetul de implementare și de programul principal. 
 + 
 +<columns 100% 100% -> 
 +<code c++ complex.h>​ 
 +class Complex { 
 +    double re; 
 +    double im; 
 +     
 +    Complex conjugate();​  
 +}; 
 +</​code>​ 
 + 
 +<​newcolumn>​ 
 + 
 +<code c++ complex.cc>​ 
 +#include "​complex.h"​ 
 +Complex Complex::​conjugate() { 
 +    Complex conjugate;​ 
 +    conjugate.re = this->​re;​ 
 +    conjugate.im = -(this->​im);​ 
 +     
 +    return conjugate;​ 
 +
 +</​code>​ 
 + 
 +<​newcolumn>​ 
 + 
 +<code c++ main.cc>​ 
 +#include <​stdio.h>​ 
 +#include "​complex.h"​ 
 + 
 +int main() { 
 +    Complex number; 
 +    number.re = 2; 
 +    number.im = 4; 
 +     
 +    printf("​%.2lf %.2lf\n",​ number.re, number.im);​ 
 +     
 +    return 0; 
 +
 +</​code>​ 
 +</​columns>​ 
 + 
 + 
 + 
 + 
 +==== Specificatori de acces ==== 
 +Am observat mesajul de eroare în urma compilării fișierelor de mai sus. 
 + 
 +Astfel, **singura diferență** folosirea celor două keyword-uri este nivelul implicit de vizibilitate a metodelor și atributelor. 
 +  ***private** - pentru clasele declarate cu **class** 
 +  ***public** ​ - pentru clasele declarate cu **struct** 
 + 
 +Membri precedați de label-ul **private** pot fi folosiți numai în interiorul clasei, în cadrul metodelor acesteia. 
 +Ei nu pot fi citiți sau modificați din afara clasei. 
 + 
 +Iată cum puteam remedia soluția: 
 +<code c++ complex.h>​ 
 +class Complex { 
 +public: 
 +    double re; 
 +    double im; 
 + 
 +    Complex conjugate();​ 
 +}; 
 +</code>
  
 ==== Constructori și destructori ==== ==== Constructori și destructori ====
Line 106: Line 198:
  
 Cei doi constructori sunt identici ca funcționalitate. Cei doi constructori sunt identici ca funcționalitate.
 +
 +==== Copy-constructor ====
 +
 +Reprezintă un tip de constructor special care se folosește când se dorește/​este necesară o copie a unui obiect existent. Dacă nu este declarat, se va genera unul default de către compilator.
 +
 +Poate avea unul din următoarele prototipuri
 +
 +   * MyClass(const MyClass&​ obj);
 +   * MyClass(MyClass&​ obj);
 +
 +=== Când se apelează? ===
 +
 +1) Apel explicit
 +
 +<code c++ explicit_copy_constructor_call.cpp>​
 +MyClass m;
 +MyClass x = MyClass(m); /* apel explicit al copy-constructor-ului */
 +</​code>​
 +
 +2) Transfer prin valoare ca argument într-o funcție
 +
 +<code c++ call_by_value.cpp>​
 +void f(MyClass obj);
 +...
 +MyClass o;
 +f(o); /* se apelează copy-constructor */
 +</​code>​
 +
 +3) Transfer prin valoare ca return al unei funcții
 +
 +<code c++ return_by_value.cpp>​
 +MyClass f()
 +{
 +    MyClass a;
 +    return a; /* se apelează copy-constructor */
 +}
 +</​code>​
 +
 +4) La inițializarea unei variabile declarate pe aceeași linie
 +
 +<code c++ init.cpp>​
 +MyClass m;
 +MyClass x = m; /* se apelează copy-constructor */
 +</​code>​
 +
  
 ==== Destructor ==== ==== Destructor ====
Line 117: Line 254:
 Dacă în constructor sau în interiorul clasei ați fi alocat memorie, cel mai probabil în destructor ați fi făcut curat și ați fi apelat free pe membrul respectiv. Dacă în constructor sau în interiorul clasei ați fi alocat memorie, cel mai probabil în destructor ați fi făcut curat și ați fi apelat free pe membrul respectiv.
  
 +==== Rule of Three ====
  
-<​hidden>​ +Reprezintă un concept ​de ** must do** pentru ​C++Astfel:
-  *[**5p**] Clasa MappingEntry - conține 2 membri de tipuri potențial diferite și realizează, din punct de vedere conceptual, asocierea între două valori (una se numește //cheie//, iar cealaltă //​valoare//​). +
-    ​*[**2p**] Implementați și folosiți utilizând template-uri clasa MappingEntry de mai sus adăugând constructor,​ destructor si 2 metode de tip getter ​pentru ​cele doua valori private. +
-    *[**2p**] Setati tipul de return a metodelor de tip getter astfel incat sa puteti modifica valorea intoarsa. +
-    *[**1p**] Arătați funcționalitatea prin adăugarea de cod în fișierul main.cpp. Rezolvați, dacă e cazul, toate erorile/​leak-urile depistate de Valgrind. +
-</​hidden>​+
  
-  ​*[**5p**] Clasa Complex - clasă ce implementează conceptul ​de număr complex +<note important>​Dacă programatorul și-a declarat/​definit unul dintre ​** constructor default**** operator ​de assignment** sau ** copy-constructor**, ​trebuie să îi declare/​definească și pe ceilalți 2</note>
-    ​*[**2p**] Implementați și folosiți utilizând template-uri clasa Complex, adăugând ​constructor ​și destructor. +
-    ​*[**2p**] Adăugați clasei Complex metode pentru adunarescădere și înmulțire cu un alt număr complex. +
-    *[**1p**] Arătați funcționalitatea prin adăugarea de cod în fișierul main.cpp. Rezolvați, dacă e cazul, toate erorile/leak-urile depistate de Valgrind.+
  
-  *[**3p**] Simple use of const +Explicație:​ dacă funcționalitatea vreunuia dintre cei 3 se vrea mai specială decât cea oferită default, atunci mai mult ca sigur se dorește schimbarea funcționalității default și pentru ​ceilalți 2 rămași.
-    *[**0.5p**] Creati un pointer variabil la o variabila de tip intreg constanta (in 2 moduri). +
-    *[**0.5p**] Creati un pointer constant la o variabila de tip intreg non-constanta. +
-    *[**0.5p**] Creati un pointer constant la o variabila de tip intreg constanta. +
-    *[**1.5p**] Initializati pointerul si variabila referita ​pentru ​fiecare caz. Explicati si rezolvati erorile de compilare.+
  
-  *[**5p**] Clasa MappingEntry - conține 2 membri de tipuri potențial diferite și realizează,​ din punct de vedere conceptual, asocierea între două valori (una se numește //cheie//, iar cealaltă //​valoare//​)+<code c++ rule_of_3.cpp> 
-    ​*[**2p**] Implementați și folosiți utilizând template-uri clasa MappingEntry de mai sus adăugând constructor și destructor. +class Complex 
-    ​*[**2p**] Alocați o instanță de tip MappingEntry local și dinamic ​(utilizând new / delete). +{ 
-    ​*[**1p**] Arătați funcționalitatea prin adăugarea de cod în fișierul main.cpp. Rezolvați, dacă e cazul, toate erorile/​leak-urile depistate de Valgrind. +    ​private: 
-<​hidden>​ +        int re; 
-  ​*[**5p**] Clasa Punct2D - clasă ce implementează conceptul de punct în plan +        int im; 
-    ​*[**2p**] Implementați și folosiți utilizând template-uri clasa Punct2D, adăugând ​constructor ​și destructor. +    ​public: 
-    ​*[**2p**] Adăugați clasei Punct2D metode pentru determinarea proiecțiilor pe axe (OX/OY), respectiv pentru determinarea distanței față de un alt Punct2D+        Complex() 
-    ​*[**1p**] Arătați funcționalitatea prin adăugarea de cod în fișierul main.cpp. Rezolvați, dacă e cazul, toate erorile/​leak-urile depistate de Valgrind+        { 
-  ​*[**5p**] Clasa KeyStorage +            re = 0; 
-    ​*[**2p**] Implementați și folosiți utilizând template-uri clasa KeyStorage de mai sus adăugând constructor și destructor. +            im = 0; 
-    ​*[**2p**] Alocați o instanță de tip KeyStorage local și dinamic ​(utilizând new / delete). +            ​printf("​constructor ​default\n"​);​ 
-    ​*[**1p**] Arătați funcționalitatea prin adăugarea de cod în fișierul main.cpp. Rezolvați, dacă e cazul, toate erorile/leak-urile depistate de Valgrind.+        } 
 + 
 +        Complex(const Complex&​ c) 
 +        { 
 +            re = c.re; 
 +            im = c.im; 
 +            ​printf("​copy contructor\n"​);​ 
 +        } 
 + 
 +        void operator=(const Complex&​ c) 
 +        { 
 +            re = c.re; 
 +            im = c.im; 
 +            printf("​assignment operator\n"​);​ 
 +        } 
 +}; 
 +</code>
  
 =====  Clase/​metode prietene ​ ===== =====  Clase/​metode prietene ​ =====
  
-Așa cum am văzut în primul ​laborator, fiecare membru al clasei poate avea 3 specificatori de acces:+Așa cum am văzut în primul ​articol, fiecare membru al clasei poate avea 3 specificatori de acces:
   * public   * public
   * private   * private
Line 425: Line 567:
 </​code>​ </​code>​
  
-==== Copy-constructor ==== 
  
-Reprezintă un tip de constructor special care se folosește când se dorește/​este necesară o copie a unui obiect existent. Dacă nu este declarat, se va genera unul default de către compilator. 
  
-Poate avea unul din următoarele prototipuri+<​hidden>​ 
 +  *[**5p**] Clasa MappingEntry - conține 2 membri de tipuri potențial diferite și realizează, ​din punct de vedere conceptual, asocierea între două valori (una se numește //cheie//, iar cealaltă //​valoare//​). 
 +    *[**2p**] Implementați și folosiți utilizând template-uri clasa MappingEntry de mai sus adăugând constructor,​ destructor si 2 metode de tip getter pentru cele doua valori private. 
 +    *[**2p**] Setati tipul de return a metodelor de tip getter astfel incat sa puteti modifica valorea intoarsa. 
 +    *[**1p**] Arătați funcționalitatea prin adăugarea de cod în fișierul main.cpp. Rezolvați, dacă e cazul, toate erorile/​leak-urile depistate de Valgrind.
  
-   ​* ​MyClass(const MyClass&​ obj); +  *[**5p**] Clasa Complex - clasă ce implementează conceptul de număr complex 
-   ​MyClass(MyClass&​ obj);+    *[**2p**] Implementați și folosiți utilizând template-uri clasa Complex, adăugând constructor și destructor. 
 +    ​*[**2p**] Adăugați clasei Complex metode pentru adunare, scădere și înmulțire cu un alt număr complex. 
 +    *[**1p**] Arătați funcționalitatea prin adăugarea de cod în fișierul main.cpp. Rezolvați, dacă e cazul, toate erorile/​leak-urile depistate de Valgrind.
  
-=== Când se apelează? ===+  *[**3p**] Simple use of const 
 +    *[**0.5p**] Creati un pointer variabil la o variabila de tip intreg constanta (in 2 moduri). 
 +    *[**0.5p**] Creati un pointer constant la o variabila de tip intreg non-constanta. 
 +    *[**0.5p**] Creati un pointer constant la o variabila de tip intreg constanta. 
 +    *[**1.5p**] Initializati pointerul si variabila referita pentru fiecare caz. Explicati si rezolvati erorile de compilare.
  
-1Apel explicit+  *[**5p**] Clasa MappingEntry - conține 2 membri de tipuri potențial diferite și realizează,​ din punct de vedere conceptual, asocierea între două valori (una se numește //cheie//, iar cealaltă //valoare//)
 +    *[**2p**] Implementați și folosiți utilizând template-uri clasa MappingEntry de mai sus adăugând constructor și destructor. 
 +    *[**2p**] Alocați o instanță de tip MappingEntry local și dinamic (utilizând new / delete). 
 +    *[**1p**] Arătați funcționalitatea prin adăugarea de cod în fișierul main.cpp. Rezolvați, dacă e cazul, toate erorile/​leak-urile depistate de Valgrind.
  
-<code c++ explicit_copy_constructor_call.cpp> +  *[**5p**] Clasa Punct2D - clasă ce implementează conceptul de punct în plan 
-MyClass m; +    *[**2p**] Implementați și folosiți utilizând template-uri clasa Punct2D, adăugând constructor și destructor
-MyClass x = MyClass(m)/* apel explicit al copy-constructor-ului */ +    ​*[**2p**] Adăugați clasei Punct2D metode pentru determinarea proiecțiilor pe axe (OX/OY), respectiv pentru determinarea distanței față de un alt Punct2D. 
-</code>+    *[**1p**] Arătați funcționalitatea prin adăugarea de cod în fișierul main.cpp. Rezolvați, dacă e cazul, toate erorile/leak-urile depistate de Valgrind. 
 +  ​*[**5p**] Clasa KeyStorage 
 +    *[**2p**] Implementați și folosiți utilizând template-uri clasa KeyStorage de mai sus adăugând ​constructor ​și destructor. 
 +    ​*[**2p**] Alocați o instanță de tip KeyStorage local și dinamic (utilizând new delete). 
 +    ​*[**1p**] Arătați funcționalitatea prin adăugarea de cod în fișierul main.cpp. Rezolvați, dacă e cazul, toate erorile/leak-urile depistate de Valgrind.
  
-2) Transfer prin valoare ca argument într-o funcție 
  
-<code c++ call_by_value.cpp>​ 
-void f(MyClass obj); 
-... 
-MyClass o; 
-f(o); /* se apelează copy-constructor */ 
-</​code>​ 
  
-3) Transfer prin valoare ca return al unei funcții 
- 
-<code c++ return_by_value.cpp>​ 
-MyClass f() 
-{ 
-    MyClass a; 
-    return a; /* se apelează copy-constructor */ 
-} 
-</​code>​ 
- 
-4) La inițializarea unei variabile declarate pe aceeași linie 
- 
-<code c++ init.cpp>​ 
-MyClass m; 
-MyClass x = m; /* se apelează copy-constructor */ 
-</​code>​ 
- 
-==== Rule of Three ==== 
- 
-Reprezintă un concept de ** must do** pentru C++. Astfel: 
- 
-<note important>​Dacă programatorul și-a declarat/​definit unul dintre ** constructor default**, ** operator de assignment** sau ** copy-constructor**,​ trebuie să îi declare/​definească și pe ceilalți 2</​note>​ 
- 
-Explicație:​ dacă funcționalitatea vreunuia dintre cei 3 se vrea mai specială decât cea oferită default, atunci mai mult ca sigur se dorește schimbarea funcționalității default și pentru ceilalți 2 rămași. 
- 
-<code c++ rule_of_3.cpp>​ 
-class Complex 
-{ 
-    private: 
-        int re; 
-        int im; 
-    public: 
-        Complex() 
-        { 
-            re = 0; 
-            im = 0; 
-            printf("​constructor default\n"​);​ 
-        } 
- 
-        Complex(const Complex&​ c) 
-        { 
-            re = c.re; 
-            im = c.im; 
-            printf("​copy contructor\n"​);​ 
-        } 
- 
-        void operator=(const Complex&​ c) 
-        { 
-            re = c.re; 
-            im = c.im; 
-            printf("​assignment operator\n"​);​ 
-        } 
-}; 
-</​code>​ 
-</​hidden>​ 
  
   *[**5p**] Clasa Punct2D - clasă ce implementează conceptul de punct în plan   *[**5p**] Clasa Punct2D - clasă ce implementează conceptul de punct în plan
Line 523: Line 618:
     *[**1p**] Arătați funcționalitatea prin adăugarea de cod în fișierul main.cpp. Rezolvați, dacă e cazul, toate erorile/​leak-urile depistate de Valgrind.     *[**1p**] Arătați funcționalitatea prin adăugarea de cod în fișierul main.cpp. Rezolvați, dacă e cazul, toate erorile/​leak-urile depistate de Valgrind.
  
-<​hidden>​+
 ===== Interviu ===== ===== Interviu =====
  
-Această secțiune nu este punctată și încearcă să vă facă o oarecare idee a tipurilor de întrebări pe care le puteți întâlni la un job interview (internship,​ part-time, full-time, etc.) din materia prezentată în cadrul ​laboratorului.+Această secțiune nu este punctată și încearcă să vă facă o oarecare idee a tipurilor de întrebări pe care le puteți întâlni la un job interview (internship,​ part-time, full-time, etc.) din materia prezentată în cadrul ​articolului.
  
   * Care este diferența între struct și class în C++?   * Care este diferența între struct și class în C++?
sd-ca/laboratoare/laborator-02.1456076236.txt.gz · Last modified: 2016/02/21 19:37 by radu.stochitoiu
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