You are on page 1of 10

Lucrarea de laborator nr.

2
Tema: Clase (constructori, destructori).Funcii i clase prietene.

Scopul lucrrii: familiarizarea studenilor cu noiunea de clase, utilizarea constructorilor,


destructorilor, cu noiunile de funcii i clase prietene.

Consideraiile teoretice necesare:


Clase
Sintaxa simplificat a declarrii unei clase este urmtoarea:
class NumeClas
{
...
declaraii variabile membri
...
declaraii funcii membri
...
}
Din definirea clasei se poate observa c clasa este asemntoare cu o structur. Ea are n
componena sa membri att de tip variabil, ct i de tip funcie. Pentru datele din interiorul clasei
se utilizeaz, de regul, termenul de date membri, iar pentru funcii denumirea de funcii sau
metode. O clas permite incapsularea n interiorul sau a datelor i a codului.
Pentru a putea utiliza efectiv un tip de date (n cazul de fa o clas), trebuie sa definim o
variabil de acel tip. ntr-un mod similar declaraiei
int i;
putem scrie:
NumeClas variabil
Vom considera c variabil este un obiect. Exprimarea uzual este c un obiect este instanierea
unei clase.
O clas este compus din dou pri: declaraia i implementarea ei. Declaraia clasei
prezint membrii clasei. Membrii clasei snt variabile de instaniere i funcii membri indicate
prin prototipul lor (tipul returnat, numele funciei, lista de parametri). Implementarea funciilor
membri are loc prin implementarea clasei. Gradul de accesibilitate la elementele componente ale
clasei este indicat prin cuvintele: private sau protected elementele clasei snt accesate numai
prin intermediul funciilor membri sau prietene friend, public toate elementele snt disponibile
n exteriorul clasei. De exemplu:
#include<iostream.h>
class myclass // se declar un nou tip de date myclass
{private: int a; // componenta int a se declar implicit n //zona private
public: // funciile membri declarate mai joc snt din //zona public
void set_a (int num); // prin intermediul acestor funcii se
// acceseaz componenta a
int get_a ();
};
void myclass::set_a(int num) { a=num;}
// aceast funcie atribuie valoare componentei a
int myclass::get_a(){return a; }

1
// aceast funcie furnizeaz valoarea componentei a
void main () // funcia de baz a programului
{ myclass ob1, ob2; // se declar dou obiecte ob1 i ob2 //de tipul myclass
ob1.set_a (10); // pentru obiectul ob1 se atribuie
//valoare componentei a egal cu 10
ob2.set_a (99); // pentru obiectul ob2 se atribuie
//valoare componentei a egal cu 99
cout << ob1.get_a ()<< \n; // pentru obiectul ob1 se //furnizeaz valoarea
componentei a
//care apoi se tiprete la ecran
cout << ob2.get_a () << \n; // pentru obiectul ob2 se //furnizeaz valoarea
componentei a
//care apoi se tiprete la ecran
}
Rezultatul ndepliniri programului:
10
99
Funciile set_a i get_a, pentru setarea i furnizarea valorii pentru componenta a, nu snt
necesare,dac componenta a va fi inclus n zona public,. Componenta a va fi explicit accesat i
i se va iniializa sau atribui valoare. Exemplul de mai sus se va modifica n felul urmtor:
#include<iostream.h>
class myclass // se declar un nou tip de date myclass
{public:
int a; // componenta int a se declar explicit n
//zona public
// funciile membri declarate mai sus nu snt necesare
};
void main ()
{ myclass ob1, ob2; // se declar dou obiecte ob1 i ob2 //de tipul myclass
ob1.a =10; // pentru obiectul ob1 se iniializeaz //valoarea componentei a n
mod
//explicit cu valoarea 10
ob2.a = 99; // pentru obiectul ob2 se iniializeaz //valoarea componentei a n mod
// explicit cu valoarea 99
cout << ob1.a << \n; // pentru obiectul ob1
// se tiprete valoarea componentei a
cout << ob2.a << \n; // pentru obiectul ob2
// se tiprete componentei a
}
Rezultatul ndepliniri programului:
10
99
Constructorii snt un tip special de funcie membru, avnd acelai nume ca i numele
clasei, nu returneaz rezultat i snt apelai automat la instanierea unei clase, fie ea static sau
dinamic. Ei au scopul de a atribui valori iniiale elementelor membri, dar pot efectua i unele
operaii, cum ar fi, alocarea dinamic de memorie, deschiderea unui fiier .a. De exemplu:

2
class persoana
{ private:
char nume[40];
long int telefon;
public:
persoana() {nume=\0; telefon =0;};
//constructorul iniializeaz valori nule elementelor membri
persoana(char*p, long int t) {strcpy(nume,p); telefon=t;}
//constructor iniializeaz valori concrete pentru elementele //membri ale clasei
persoana(char* nume) {return nume; };
//aceste funcii atribuie valori pentru elementele membri nume
persoana(long int telefon) {return telefon;}; //i telefon
persoana persoana_ input (char *n, long int t=0)
{persoana p;
strcpy(p.nume,n); p.telefon=t;
return p; };
};
Apelul constructorului se efectueaz n momentul declarrii unui obiect. Dac declarm o
variabil de tipul persoana, fie
persoana p = persoana (Vasilina, 743567);
sau
persoana p (Vasilina, 743567);
constructorul va iniializa elementele membri nume i telefon ale clase persoana respectiv cu
valorile Vasilina i 743567. Dac se va declara un obiect de tipul persoana fr date iniiale,
constructorul va completa elementele membri nume cu stringul vid \0 i telefon cu valoarea 0.
Destructorii dezactiveaz toate funciile unui obiect, l distruge i snt apelai automat la
eliminarea unui obiect, la ncheierea timpului de via n cazul static, sau la apelul unui delete n
cazul dinamic. De regul, destructorii snt utilizai n cazul, cnd constructorii efectueaz alocri
dinamice de memorie. Destructorul are acelai nume ca i constructorul, fiind precedat de
semnul ~. De exemplu:
#include<iostream.h>
#include<string.h>
#include<stdlib.h>
#define Size 255
class strtype
{ private:
char *p;
int len;
public:
strtype() // constructorul
{ p=new char;
if (!p){cout << Eroare la alocarea memoriei \n; exit(1);}
*p=\0; len=0; };
~strtype() {cout << Eliberarea memoriei\n; delete p; }
// destructorul
void set (char*ptr)

3
{ if (strlen(ptr)> Size )
cout<<Stringul conine mai mult de 255 de caractere \n; strcpy(p,ptr);
len=strlen(p);};
void show()
{ cout << p << - lungimea << len << \n;}
};
void main()
{ strtype s1,s2;
s1.set (Test); s2.set(Program C++);
s1.show(); s2.show();
}
Rezultatul ndeplinirii programului:
Test- lungimea 4
Program C++- lungimea 11
Eliberarea memoriei
Eliberarea memoriei
Destructorii obiectelor membri snt apelai, dup ce destructorul obiectului principal a fost
executat. Dac obiectul membru este compus din alte obiecte, atunci se va proceda la executarea
destructorilor obiectelor incluse. Destructorii obiectelor membri snt apelai n ordine invers, n
care acetea apar n declaraia clasei.
Din punct de vedere cronologic, constructorul este apelat dup alocarea memoriei
necesare, deci n faza final a crerii obiectului, iar destructorul naintea eliberrii memoriei
aferente, deci n faza iniial a distrugerii sale.
Constructorii i destructorii se declar i se definesc similar cu celelalte funcii membri,
dar prezint o serie de caracteristici specifice:
numele lor coincide cu numele clasei creia ii aparin; destructorii se disting de constructori
prin faptul c numele lor este precedat de caracterul
nu pot returna nici un rezultat
nu se pot utiliza pointeri ctre constructori sau destructori
constructorii pot avea parametri, destructorii insa nu. Un constructor fr parametri poart
denumirea de constructor implicit.
n care o clasa nu dispune de constructori sau destructori, compilatorul de C++ genereaz
automat un constructor, respectiv destructor, implicit.
Membrii unei clase
Accesarea membrilor unei clase se face n felul urmtor:
obiect.VariabiMembru = valoare;
pentru accesul la o variabil membru, i
obiect.FuncieMembru();
pentru apelarea unei funcii membri.
Pentru exemplificare s consideram o implementare a noiunii de punct. Ca variabile
membri avem nevoie doar de coordonatele x i y care definesc poziia n spaiu a unui punct. Am
mai declarat o funcie care calculeaz aria dreptunghiului avnd punctele (0, 0) i (x, y).
class Point
{unsigned x, y;
unsigned long Arie() {return x * y;};
unsigned GetX();

4
unsigned GetY();
void SetX(unsigned X);
void SetY(unsigned Y);
};
unsigned Point::GetX() {return x;}
unsigned Point::GetY(){return y; }
void Point::SetX(unsigned X){ x = X; }
void Point::SetY(unsigned Y) { y = Y; }
Am folosit un operator nou, specific C++, ::, numit operator de rezoluie, numit i operator de
acces sau de domeniu. El permite accesul la un identificator dintr-un bloc n care acesta nu este
vizibil datorit unei alte declaraii locale. Un exemplu de folosire este urmtorul:
char *sir = "variabil global";
void funcie()
{ char *sir = "variabil local";
printf("%s\n", ::sir); // afieaz variabila global
printf("%s\n", sir); // afieaz variabila local
}
Pentru definiiile funciilor membri aflate n afara declaraiei clasei este necesar specificarea
numelui clasei urmat de acest operator, indicnd faptul c funcia are acelai domeniu cu
declaraia clasei respective i este membru a ei, dei este definit n afara declaraiei.
Cuvntul-cheie this. Toate funciile membri ale unei clase primesc un parametru ascuns,
pointer-ul this, care reprezint adresa obiectului n cauz. Acesta poate fi utilizat n cadrul
funciilor membri. De exemplu:
unsigned long Point::Arie()
{return this->x * this->y; }
Crearea i distrugerea obiectelor. S considerm urmtorul program C++:
void main()
{Point p; }
n momentul definirii variabilei p, va fi alocat automat spaiul de memorie necesar, acesta
fiind eliberat la terminarea programului. n exemplul de mai sus, variabila p este de tip static. n
continuare vom modifica acest program pentru a folosi o variabil dinamic (pointer).
void main()
{ Point *p;
p = new Point;
p->x = 5; p->y = 10;
printf("Aria = %d\n", p->Aria());
delete p; }
Operatorul new este folosit pentru alocarea memoriei, iar sintaxa acestuia este:
variabila = new tip;
variabila = new tip(valoare_iniial);
variabila = new tip[n];
Prima variant aloc spaiu pentru variabil dar nu o iniializeaz, a doua variant ii aloc spaiu
i o iniializeaz cu valoarea specificat, a treia aloc un tablou de dimensiune n. Acest operator
furnizeaz ca rezultat un pointer coninnd adresa zonei de memorie alocate, n caz de succes, sau
un pointer cu valoarea NULL (practic 0) cnd alocarea nu a reuit.

5
Eliminarea unei variabile dinamice i eliberarea zonei de memorie aferente se realizeaz
cu ajutorul operatorului delete. Sintaxa acestuia este:
delete variabil;
Dei aceti doi operatori ofer metode flexibile de gestionare a obiectelor, exist situaii n care
aceasta nu rezolv toate problemele. De aceea, pentru crearea i distrugerea obiectelor n C++ se
folosesc nite funcii membri speciale, numite constructori i destructori, despre care s-a
menionat mai sus.
S completm n continuare clasa Point cu un constructor i un destructor:
Point::Point() // constructor implicit
{ x = 0; y = 0; }
Point::Point(unsigned X, unsigned Y)
{ x = X; y = Y; }
Point::~Point() { }
Ai remarcat cu aceast ocazie modul de marcare a comentariilor n C++: tot ce se afl dup
caracterul // este considerat comentariu.
Definiii de forma
Point p; //sau
Point *p = new Point();
duc la apelarea constructorului implicit.
O ntrebare care poate apare este motivul pentru care am realizat funciile GetX(), GetY(),
SetX(), SetY(), cnd puteam utiliza direct variabilele membri x i y. Deoarece una din regulile
programrii C++ este de a proteja variabilele membri, acestea pot fi accesate numai prin
intermediul unor funcii, care au rolul de metode de prelucrare a datelor incapsulate n interiorul
clasei.
Funcii i Clase friend. Conceptul friend permite abateri controlate de la ideea proieciei
datelor prin incapsulare. Mecanismul de friend (sau prietenie) a aprut datorita imposibilitii ca
o metod s fie membru a mai multor clase.
Funciile prietene snt funcii care nu snt metode ale unei clase, dar care au totui acces la
membrii privai ai acesteia. Orice funcie poate fi prieten a unei clase, indiferent de natura
acesteia.
Sintaxa declarrii unei funcii prietene n cadrul declaraiei unei clase este urmtoarea:
friend NumeFuncie
De exemplu:
class Point {
friend unsigned long Calcul(unsigned X, unsigned Y);
public:
friend unsigned long AltClas::Calcul(unsigned X,
unsigned Y);
... };
unsigned long Calcul(unsigned X, unsigned Y)
{return X * Y / 2; }
unsigned long AltClas::Calcul(unsigned X, unsigned Y)
{ ... }
Funcii membri ca prietene. Orice funcie membru nu poate fi prieten aceleiai clase, dar,
posibil, s fie prietena altei clase. Astfel, funciile friend constituie o punte de legtur ntre
clase. Exist dou moduri de a face ca o funcie membru a unei clase s fie prietena altei clase.

6
Prima variant este specificarea funciei membru a unei clase, ca fiind prieten altei clase. Deci,
n cea de-a doua clas, vom declara funcia membru n prima clas ca fiind de tip friend.
class B;
class A
{..
void Al (B &x) ;
..
);
class B
{ friend void A::A1(B &x); );
A doua variant este declararea unei clase prieten, astfel, c toate funciile sale membri, snt, de
fapt, prietene clasei n care un obiect de tipul primei clase este declarat friend.
class B;
class A
{ void Al (B &x) ; );
class B
{
friend A;
};
Indiferent de metod, se impune predeclararea clasei, care va fi prieten sau va conine funcii,
care snt prietene unei alte clase.
Clasele prietene snt clase care au acces la membrii privai ai unei clase. Sintaxa declarrii
unei clase prietene este:
friend class NumeClasPrieten
De exemplu:
class PrimaClas {
...
};
class ADouaClas {
...
friend class PrimaClas;
};
Clasa PrimaClas are acces la membrii privai ai clasei ADouaClas.
Relaia de prietenie nu este tranzitiv. Daca o clasa A este prietena a clasei B, i clasa B
este prieten a unei clase C, aceasta nu nseamn ca A este prieten clasei C. De asemenea,
proprietatea de prietenie nu se motenete n clasele derivate. Clase prietene snt utile n situaia
n care avem nevoie de clase, care s comunice ntre ele deseori, acestea aflndu-se pe acelai
nivel ierarhic. Pentru exemplificare, presupunem c vom implementa o stiv de caractere ca o
list simplu nlnuit. Vom utiliza dou clase, una ataat nodurilor din list i una stivei
propriu-zise.
#include<conio.h>
#include<stdio.h>
class stiva;
class nod
{ private:
friend stiva;

7
nod(int d, nod *n);
int data;
nod *anterior;
};
class stiva
{ private:
nod *virf;
public:
stiva () { virf=NULL; }
~stiva() { delete virf; }
void push (int c);
int pop ();
};
nod::nod (int d, nod *n) {data=d; anterior=n;}
void stiva::push (int i) {nod *n=new nod(i, virf); virf=n; }
int stiva::pop ()
{ nod *t=virf;
if (virf)
{ virf=virf->anterior;
int c= t->data;
delete t;
return c; }
return -1;
}
void main()
{ int c;
stiva cs;
printf("Introdu un sir de caractere, ce se termina in *");
while ((c=getch ())!='*')
{ cs.push (c);
putch(c); }
putch(c);
while ((c=cs.pop ())!=-1)
{ putch (c); }
c='\n'; putch(c);
}
Rezultatul ndeplinirii programului:
Introdu un sir de caractere, ce se termina in *ertyuioppoiu*uiop
poiuytre
Prototipul unei funcii friend cu o clas se afl, de regul, n cadrul clasei respective. Funcia
friend nu este membru a acestei clase. Indiferent de poziia declaraiei unei asemenea funcii, n
cadrul declaraiei clasei funcia va fi public. De exemplu:
class punct
{ private:
int x, y;
public:

8
punct (int xi, int yi) {x=xi; y=yi; };
friend int compara (punct &a, punct &b);
};
int compara (punct &a, punct &b)
{ //returneaz <0, dac a este mai aproape de origine
// >0, dac b este mai aproape de origine
// =0, dac a i b snt egal deprtate.
return a. x*a. x+a. y*a. y-b. x*b. x-b. y*b. y; }
void main()
{ punct p (14,17), q(57,30);
if(compara(p,q)<0) printf("p este mai apropiat de origine\n");
else printf (q este mai apropiat de origine. \n") ; }
Orice funcie friend a unei clase poate fi transformat ntr-o funcie membru a acelei clase,
renunndu-se ns la gradul de prietenie. Exemplul de mai sus se modific n felul urmtor:
#include<stdio.h>
class punct
{ private:
int x,y;
public:
punct (int xi, int yi) { x=xi; y=yi; }
int compara (punct &b);
};
int punct:: compara (punct &b)
{ return x*x+y*y-b.x*b.x-b.y*b.y; }
void main ()
{ punct p(14,17), q(57,30);
if (p.compara (q)<0)printf ("p este mal apropiat de origine\n");
else printf ("q este mai apropiat de origine.\n");
}
Rezultatul ndeplinirii programului:
p este mal apropiat de origine

9
Tema pentru lucrrea de laborator:

S se scrie un program pentru implimentarea unei clase care include un set de date
specifice ct i urmtoarele metode:

- Constructor prestabilit,
- Constructor de copiere,
- Constructor cu parametri,
- Metod de iniializare a datelor,
- Metod de afiare a datelor,
- Metode de returnare i afiare separat a datelor(opional).

Clasa va conine metode descrise att n interior ct i n exteriorul ei. Cel puin o
metod va fi declarat ca funcie prieten. Dup posibiliti s se utilizeze pointerul
this i operatorul rezoluie( ::).

Sarcin individual.

Varianta:

1. Apartament Numar de odi, suprafaa, etajul.


2. Motociclet Numele de firm, numarul de roi, volumul motorului.
3. Calculator firma, viteza procesorului, capacitatea memoriei.
4. Camion numele de firma, tonajul, distana parcurs.
5. Continent emisfera, suprafaa ,numarul de locuitori.
6. Elev numele, clasa, balul mediu.
7. Film denumirea, anul emiterii, costul filmrii.
8. Medic specialitate, staj, salariul.
9. Ora continent, ara, numr de locuitori.
10.Patrulater numele, numrul de laturi, suprafaa.
11.Piramid forma bazei, inalimea, suprafaa total.
12.Profesor numele, specialitatea, vrsta.
13.Ru continent, lungimea, debitul de ap.
14.Sportiv numele, ara, numrul de medalii.
15.ar continentul, numarul de locuitori, suprafaa.

10

You might also like