- •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
§15. Supraîncărcarea operatorilor prin funcţii prietene
Supraîncărcarea prin intermediul funcţiilor prietene este necesară în unele situaţii pentru eficienţă, iar în unele situaţii concrete este unica metodă de supraîncărcare a operatorilor. Considerăm următoarea problemă: în clasa complex este supraîncărcat operatorul + ce oferă posibilitatea de a aduna un număr complex cu un număr real cu virgulă mobilă, rezultatul fiind, desigur, un număr complex. Supraîncărcarea este efectuată prin metoda funcţiilor membre. O descriere schematică a acestei situaţii urmează în continuare:
class complex
{
. . .
complex operator + (float f)
{
. . .
}
. . .
};
. . .
complex c1(5,7), r; // c1+f
float f=2.7 ;
. . .
r= c1+f;
Utilizarea operatorului + pentru calcularea lui c1+f este corectă, dar apare următoarea întrebare: e posibil oare a utiliza o expresie de felul f+c1? Din punct de vedere matematic sunt expresii echivalente, dar din punctul de vedere al programării, va fi generată o eroare din motiv că variabila f este de tip real cu virgulă mobilă şi nu are definită adunarea cu un număr complex. Deci, trebuie de definit o funcţie care ar putea calcula expresiile de tipul f+c1. Dar supraîncărcarea directă a operatorului + prin metoda funcţiilor membre este imposibilă. Astfel, se va recurge la aplicarea metodei de supraîncărcare prin metoda funcţiilor prietene. În asemenea situaţii, se obţine mai multă eficienţă, putând utiliza în expresii proprietatea de comutativitate.
A fost menţionat deja faptul că unii operatori pot fi supraîncărcaţi doar prin metoda funcţiilor prietene. Ca exemplu pot fi aduşi operatorii de inserţie şi extragere (intrarea/ieşirea informaţiei) care acceptă supraîncărcarea doar prin metoda funcţiilor prietene.
Pentru a realiza supraîncărcarea unui operator prin metoda funcţiilor prietene, se realizează următoarea schemă generală:
class nume_cl
{
. . .
friend tip_r operator Ø (lista_pf);
. . .
};
tip_r operator Ø (lista_pf)
{
. . .
}
unde Ø este numele operatorului supraîncărcat, iar lista_pf reprezintă lista parametrilor fictivi ai funcţiei. Fiindcă o funcţie prietenă nu are acces la pointerul this, lista parametrilor fictivi conţine de regulă doi parametri pentru operatorii binari sau un parametru fictiv pentru operatori unari.
Exemplu. De alcătuit un program în care este implementată clasa complex, definind operatorii caracteristici numerelor complexe prin supraîncărcarea operatorilor prin metoda funcţiilor prietene.
#include <iostream.h>
#include <iomanip.h>
class complex
{
float r, i;
public:
complex (float r1=0, float i1=0)
{ r=r1; i=i1; }
friend complex operator +(complex a,complex b);
friend complex operator *(complex a,complex b);
friend complex operator +=(complex &a,complex b);
friend complex operator +(complex c,float f);
friend complex operator +(float f,complex c);
void afisare ();
};
//------------------
complex operator + (complex a, complex b)
{
complex c;
c.r = a.r + b.r ;
c.i = a.i + b.i ;
return c ;
}
//------------------
complex operator + (complex a, float f)
{
complex c;
c.r = a.r + f;
c.i = a.i;
return c;
}
//------------------
complex operator + (float f, complex a)
{
complex c;
c = a + f;
return c;
}
//------------------
complex operator += (complex &a, complex b)
{
a.r += b.r ;
a.i += b.i;
return a;
}
//------------------
complex operator * (complex a, complex b)
{
complex p;
p.r = a.r * b.r – a.i * b.i;
p.i = a.r * b.i + a.i * b.r;
return p;
}
//------------------
void complex :: afisare ()
{
cout << r << setiosflafs (ios :: showpos)
<< i << "i"
<< resetiosflags (ios :: showpos);
}
//==================
void main ()
{
complex a(2,4), b(-3, 7.2), s, p;
float f1=2.7;
s=f1+a;
s.afisare();
(a*b+f1).afisare();
b+=a;
b.afisare();
}
