- •Programare orientată pe obiecte
- •§1. Principiile programării orientate pe obiecte.
- •§3. Constructori şi destructori.
- •8) Aceste mesaje apar după ce se termină lucrul programului.
- •§4. Operaţii de intrare/ieşire a informaţiei.
- •§5. Moştenire simplă.
- •§6. Moştenire multiplă
- •§7. Moştenirea pe mai multe niveluri. Clase virtuale
- •§9. Definirea şi utilizarea referinţelor
- •§10. Tablouri de obiecte. Pointeri şi referinţe la obiecte. Pointeri la membrii clasei
- •§11. Dirijarea dinamică a memoriei
- •§12. Constructor de copiere
- •§13. Funcţii prietene şi clase prietene
- •§14. Supraîncărcarea operatorilor
- •§15. Supraîncărcarea operatorilor prin funcţii prietene
- •§16. Supraîncărcarea unor operatori speciali
- •Operatorii de incrementare şi decrementare
- •Operatorii de inserţie şi extragere
- •Operatorul indice
- •Operatorul funcţie
- •Operatorii new şi delete
- •Operatorul virgulă
- •Operatorul de conversie
- •§17. Funcţii-şablon şi clase-şablon
- •§18. Realizarea conceptului de polimorfism
- •§19. Clase abstracte
- •§20. Membrii statici ai clasei
- •§23. Tratarea excepţiilor
- •Bibliografie
§13. Funcţii prietene şi clase prietene
Clasele sunt proiectate în corespundere cu principiile caracteristice tipurilor abstracte de date. Ele au o serie de proprietăţi, care, de regulă, sunt închise pentru lumea exterioară şi o serie de operaţii care determină funcţionalitatea tipului dat şi care permit şi accesul la proprietăţile tipului dat. Atunci când este necesar un proces rapid de prelucrare, apelarea multor funcţii încetineşte procesul de execuţie şi pentru sistemele de execuţie în timp real nu este efectivă.
Dacă ar fi proiectate clasele vector şi matrice, ar putea fi necesară şi operaţia produs matrice-vector. Dacă nu este logică definirea acestei operaţii ca operaţie internă a uneia dintre clase, atunci ea va fi definită ca o funcţie externă. Schematic această situaţie poate fi reprezentată astfel:
class vector
{
. . .
int el_v[100];
int dim;
. . .
public:
. . .
int element_v (int ind);
void sc_elem_v (int ind, int v_n);
int dimensiune_v();
. . .
};
//--------------
class matrice
{
. . .
int el_m[100][100];
int dim;
. . .
public:
. . .
int element_m (int ind1, int ind2);
void sc_elem_m (int ind1, int ind2, int v_n);
int dimensiune_m();
. . .
};
//--------------
//functie externa care realizeaza
//produsul matrice-vector
vector prod_m_v (matrice m, vector v)
{
vector vr;
int i, j, s;
. . .
for (i=0;i<v.dimensiune_v();i++)
{
s=0;
for(j=0;j<v.dimensiune_v();j++)
s+=m.element_m(i,j) * v.element_v(j);
vr.sc_elem_v(i,s);
}
. . .
return vr;
}
Din definirea funcţiei prod_m_v() se poate vedea că ea conţine foarte multe apeluri de funcţie, ceea ce sigur măreşte timpul de execuţie.
Deoarece în unele situaţii poate fi necesar un acces mai rapid la unele resurse ale clasei, s-a convenit a permite, în unele situaţii, unor funcţii externe acces direct la membrii privaţi sau protejaţi ai clasei date. Astfel de funcţii sunt numite funcţii prietene ale clasei date. Pentru ca o funcţie să fie recunoscută drept funcţie prietenă, ea trebuie să fie declarată prietenă în interiorul clasei. Descrierea este înfăptuită cu ajutorul cuvântului-cheie friend. Nu are importanţă locul de plasare a descrierii. Descrierea corespunzătoare poate fi plasată în câmpul de acţiune a oricărui modificator de acces:
class nume_cl
{
. . .
friend tipr nume_func_pr(lista_par_fictivi);
. . .
};
Definirea funcţiei se face în mod obişnuit ca orice altă funcţie externă clasei. Modificatorul friend nu este plasat în antetul funcţiei la definire:
tipr nume_func_pr(lista_par_fictivi)
{
. . .
//instructiuni
. . .
}
Dacă descrierea
friend vector prod_m_v (matrice m, vector v);
va fi plasată în declarările claselor vector şi matrice, atunci funcţia prod_m_v() va deveni prietenă a claselor date. Dacă este declarată drept funcţie prietenă, atunci poate fi simplificat modul ei de realizare obţinându-se acces direct la toţi membrii claselor. După ce o declarăm funcţie prietenă, ea va avea următoarea realizare:
//functie externa care realizeaza
//produsul matrice-vector
vector prod_m_v (matrice m, vector v)
{
vector vr;
int i, j;
. . .
for (i=0; i<v.dimensiune_v(); i++)
{
vr.el_v[i] = 0;
for (j=0; j<v.dimensiune_v(); j++)
vr.el_v[i] += m.el_m[i][j] * v.el_v[j];
}
. . .
return vr;
}
O funcţie prietenă unei clase poate fi funcţie membră a altei clase. La declararea ei ca funcţie prietenă numele ei este precedat de numele clasei din care face parte:
class nume_cl
{
. . .
friend tipr nume_clasa::nume_fp(lista_pf);
. . .
};
Atunci când toate funcţiile membre ale unei clase sunt prietene a altei clase, este obţinută noţiunea de prietenie a claselor, adică prima clasă este prietenă cu cea de-a doua.
class B
{
. . .
// membri
. . .
};
class A
{
. . .
friend class B;
. . .
};
Relaţia de prietenie în cadrul claselor nu este una comutativă. Adică dacă clasa A este prietenă cu B, aceasta nu înseamnă că clasa B este prietenă cu A.
Tot aşa ea nu este una tranzitivă. Dacă clasa A este prietenă cu B şi clasa B este prietenă cu C, aceasta nu înseamnă că clasa A este prietenă cu C.
