Documente Academic
Documente Profesional
Documente Cultură
};
n Definiţia funcţiei se face în afara clasei
tip_ret id_functie_prieten(lista_de_parametri) {
double distanta(Punct p1, Punct p2) {
//corpul de instructiuni în care avem acces la datele protejate ale obiectelor clasei IdClasa
return sqrt((p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y));
} }
Clase si funcții friend. Supraîncărcarea operatorilor 2 Clase si funcții friend. Supraîncărcarea operatorilor 4
Funcții friend globale. Exemplu Funcții friend membre ale altor clase
class Punct {
Funcția distanta este declarată
private: class Punct; PoligonConvex::PoligonConvex(int n, Punct v[]){
double x, y; funcție prieten a clasei Punct this -> n = n;
Definiția funcției afiseaza.
public: class PoligonConvex{ varfuri = new Punct[n];
Punct *varfuri; for (int i=0;i<n;i++){ Avem acces asupra
Punct(double x=0, double y=0){ int n; varfuri[i] = v[i]; datelor private x și y din
this -> x = x; public: } clasa Punct
this -> y = y; PoligonConvex (int n, Punct v[]); }
} ~PoligonConvex(); PoligonConvex::~PoligonConvex(){
friend double distanta(Punct p1, Punct p2); void afiseaza(); delete []varfuri;
}; }
};
class Punct { void PoligonConvex::afiseaza() {
double distanta(Punct p1, Punct p2) { private: cout<<"[";
return sqrt((p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y)); double x, y; for (int i=0;i<n;i++){
} public: cout<<"("<< varfuri[i].x << ","
Punct(double x=0, double y=0); << varfuri[i]. y<<")";
friend void PoligonConvex::afiseaza(); }
int main(){ }; cout<<"]";
Punct p1(1,0), p2(4,4); }
cout<<"distanta="<< distanta (p1,p2); Punct::Punct(double x, double y){
getch(); Definiția funcției distanta. this -> x = x; int main(){
this -> y = y; Punct t[3]={Punct(0,0), Punct(3,0),
} Avem acces asupra datelor } Punct(3,4)};
private x și y din clasa Punct PoligonConvex p(3,t);
p.afiseaza();
}
Clase si funcții friend. Supraîncărcarea operatorilor 5 Clase si funcții friend. Supraîncărcarea operatorilor 7
Clase si funcții friend. Supraîncărcarea operatorilor 6 Clase si funcții friend. Supraîncărcarea operatorilor 8
Clase friend (II)
n Relaţia de prietenie dintre două clase nu este reflexivă:
Dacă clasa IdClasaA este clasă prieten a clasei IdClasaB, Supraîncărcarea
atunci nu şi reciproca este valabilă
n Relaţia de prietenie nu este tranzitivă: dacă clasa operatorilor
IdClasaA este clasă prietenă clasei IdClasaB, iar IdClasaB
este clasă prietenă clasei IdClasaC, asta nu implică
faptul că IdClasaA este clasă prietenă a clasei IdClasaC.
n Relaţia de prietenie nu se moşteneşte în clasele
derivate.
};
friend class Segment; return sqrt((o.x-v.x)*(o.x-v.x)+
(o.y-v.y)*(o.y-.y)); efectua cu acestea. De exemplu: adunare (+),
}
class Segment{
Punct o;
void Segment::afisare() {
cout<<"[";
scadere (-), etc.
Punct v; o.afisare();
public:
Segment (Punct o, Punct v);
cout<<",";
v.afisare(); Avem acces la date n Problemă: în cazul tipurilor de date definite
double lungime(); cout<<"]"; şi metode private
};
void afisare(); }
int main(){
din clasa Punct
prin intermediul claselor am putea definii
Punct o(1,0), v(4,4);
Punct::Punct(double x, double y){
this -> x = x;
Segment s(o,v);
s.afisare();
anumite operații cu ajutorul operatorilor?
this -> y = y; cout<<"\nLungime ="<< s.lungime();
} getch();
}
Clase si funcții friend. Supraîncărcarea operatorilor 10 Clase si funcții friend. Supraîncărcarea operatorilor 12
Exemplu: Operații cu numere complexe Supraîncărcarea operatorilor
class Complex { Complex Complex::adunare(Complex z){
private: Complex rez;
float re; rez.re = this->re + z.re;
float im;
public:
rez.im = this->im + z.im;
return rez;
n Este procesul de atribuire a două sau mai
Complex (float re=0, float im=0);
void afisare();
Complex adunare(Complex z);
}
Complex Complex::conjugatul(){
multor operații aceluiași operator.
Complex conjugatul(); return Complex(re,-im);
friend Complex diferenta(Complex z1,
Complex z2);
}
n Se poate realiza prin
}; Complex diferenta(Complex z1, Complex z2){
}
this->im = im; Complex z1(2,1), z2(3,4), z;
z=z1.adunare(z2);
¨ Funcții friend globale
z=diferenta(z1,z2);
void Complex::afisare(){ z=z1.conjugatul();
printf("%-g%+g*i\n", re, im);
} }
Clase si funcții friend. Supraîncărcarea operatorilor 13 Clase si funcții friend. Supraîncărcarea operatorilor 15
Clase si funcții friend. Supraîncărcarea operatorilor 14 Clase si funcții friend. Supraîncărcarea operatorilor 16
Supraîncărcarea operatorilor cu funcții membru Supraîncărcarea operatorilor. Exemplu
lista de parametri (operanzi asupra class Complex { Complex Complex::operator +(Complex z){
private: Supraîncărcare cu Complex rez;
n Sintaxa carora acționează operatorul) float re;
float im;
funcţii membru rez.re = this->re + z.re;
rez.im = this->im + z.im;
class IdClasa { public: }
return rez;
Clase si funcții friend. Supraîncărcarea operatorilor 17 Clase si funcții friend. Supraîncărcarea operatorilor 19
Clase si funcții friend. Supraîncărcarea operatorilor 18 Clase si funcții friend. Supraîncărcarea operatorilor 20
Supraîncărcarea operatorilor ++ și -- Supraîncărcarea operatorului =
class Complex { Complex& operator --(Complex& z){
private: z.re -=1;
float re; printf("predecremntare\n");
float im;
}
return z; n Dacă o clasă nu are supraîncărcat operatorul egal
public:
Complex (float re=0, float im=0);
Complex& operator --(Complex& z, int n){
z.re -=1; atunci compilatorul va genera o supraîncarcare
void afisare(); printf("postdecrementare\n");
Complex& operator ++();
Complex& operator ++(int); }
return z; standard care va realiza copierea bit cu bit a datelor
friend Complex& operator --(Complex& z);
friend Complex& operator --(Complex& z,int n);
int main(){
Complex z(4,5);
membru
z.afisare();
}; ++z; z.afisare();
z++; z.afisare();
n Dacă o clasă conține date membru obiecte ale altor
Complex& Complex::operator ++(){
re +=1;
--z; z.afisare();
z--; z.afisare(); OUTPUT clase și nu are supraîncărcat operatorul =, atunci
printf("preincrementare\n"); }
}
return *this; 4+5*i
preincrementare
constructorul generat de compilator va apela la
Complex& Complex::operator ++(int n){
5+5*i
postincrementare supraîncarcarile operatorului = pentru copierea
re +=1; 6+5*i
printf("postincrementare\n");
return *this;
predecremntare
5+5*i
obiectelor membru
} postdecrementare
4+5*i
Clase si funcții friend. Supraîncărcarea operatorilor 21 Clase si funcții friend. Supraîncărcarea operatorilor 23
Clase si funcții friend. Supraîncărcarea operatorilor 22 Clase si funcții friend. Supraîncărcarea operatorilor 24
Exemplu II: Supraîncărcarea operatorului = Exemplu III: Supraîncărcarea operatorului =
class Persoana {
class Persoana { ~Persoana(){ . . .
private: cout<<"Distrug obiectul:"<<nume<<endl; public:
char *nume; delete nume; . . . OUTPUT
int varsta; } Persoana& operator =(const Persoana &ob){ Apel constructor cu parametri
if (this != &ob){ Apel constructor de copiere
setNume(ob.nume); Apel constructor cu parametri
public: void setNume(char *n){
setVarsta(ob.varsta); Apel supraincarcare =
Persoana(char *n="", int v=0){ if(strlen(nume)<strlen(n)){
} Nume:Misu
nume = new char[strlen(n)+1]; delete nume;
cout<<"Apel supraincarcare = \n"; Varsta:21
strcpy(nume, n); nume = new char[strlen(n)+1];
return *this; Nume:Mihai
varsta = v; }
} Varsta:21
cout<<"Apel constructor strcpy(nume, n);
}; Nume:Mihai
cu parametri\n"; }
Varsta:21
} int main(){ Distrug obiectul:Mihai
void setVarsta(int v){ Persoana p1("Mihai",21); Distrug obiectul:Mihai
Persoana(const Persoana &p){ varsta = v; Persoana p2=p1; Distrug obiectul:Misu
nume = new char[strlen(p.nume)+1]; } Persoana p3;
strcpy(nume, p.nume); p3 = p1;
varsta = p.varsta; void afisare(){ p1.setNume("Misu");
cout<<"Apel constructor de copiere\n"; cout<<"Nume:"<<nume<<endl; p1.afisare();
} cout<<"Varsta:"<<varsta<<endl; p2.afisare();
} p3.afisare();
}; }
Clase si funcții friend. Supraîncărcarea operatorilor 25 Clase si funcții friend. Supraîncărcarea operatorilor 27
Clase si funcții friend. Supraîncărcarea operatorilor 26 Clase si funcții friend. Supraîncărcarea operatorilor 28