Supraincarcarea operatorilor
Supraincarcarea
(supradefinirea, termenul overloading)
operatorilor permite atribuirea de noi semnificatii
operatorilor uzuali (operatorilor intalniti pentru
tipurile de date predefinite). Asa
cum am subliniat in numeroase randuri, clasa reprezinta un tip de date (o multime
de valori pentru care s-a adoptat un anumit mod de reprezentare si o multime de operatii care pot fi
aplicate acestora).
Astfel, operatorul + foloseste
la adunarea a doua date de tip int, float sau double, insa aceluiasi operator i se poate atribui semnificatia
de "alipire" a doua obiecte de tipul sir, sau de adunare a doua
obiecte de tipul complex, vector sau matrice.
Observatie: Operatorii sunt deja supradefiniti pentru a putea opera asupra mai multor tipuri de baza (de exemplu, operatorul + admite operanzi de tip int, dar si float sau double), sau pot avea semnificatii diferite (de exemplu, operatorul * poate fi folosit pentru inmultirea a doi operanzi numerici sau ca operator de deferentiere, operatorul >> poate avea semnificatia de operator extractor sau operator de deplasare pe biti).
Prin
supraincarcarea operatorilor, operatiile
care pot fi executate asupra instantelor (obiectelor)
unei clase pot fi folosite ca si in cazul tipurilor de date predefinite.
Deci, limbajul C++ permite supradefinirea
operatorului op prin definirea unei functii numite operator op
Unde op este un operator ca : +, -, [] , & etc.
Supradefinirea se realizeaza astfel:
tip_val_intoarsa
operator op (lista_declar_parametri)
{
// . . . . corpul functiei
}
Restrictii la supraincarcarea
operatorilor
Supraincarcarea operatorilor este supusa urmatoarelor restrictii:
- Se pot supraincarca doar operatorii existenti; nu se pot crea noi operatori.
- Nu se poate modifica aritatea (numarul
de operanzi) operatorilor limbajului (operatorii unari nu pot fi supraincarcati ca operatori binari, si invers).
- Nu se poate modifica precedenta si asociativitatea operatorilor.
- Nu pot fi supraincarcati operatorii
. ::? si :
Observatie: Daca operatorul = nu este supraincarcat, el are o semnificatie implicita.
Exemplul 1: Pentru
clasa complex , putem atribui operatorului + semnificatia:
expresia a+b (a, b sunt obiecte din clasa complex) reprezinta
"suma" a doua numere complexe si este un numar
complex. Astfel, supradefinirea operatorului + consta
in definrea unei functii cu
numele: operator +
Supraincarcarea operatorului +
#include<iostream.h>
#include<conio.h>
class
complex
{public:
float x,y;
void
display()
{cout<<x<<"+"<<y<<"*i";
cout<<endl;
}
complex operator+(complex z)
{complex s;
s.x=x+z.x;
s.y=y+z.y;
return s;
}
};
void main()
{clrscr();
complex a,b,aux;
cout<<"primul
numar "<<endl;
cout<<"partea
reala ";
cin>>a.x;
cout<<"partea
imaginara ";
cin>>a.y;
cout<<"al
doilea numar "<<endl;
cout<<"partea
reala ";
cin>>b.x;
cout<<"partea
imaginara ";
cin>>b.y;
aux=a+b;
cout<<endl<<"Suma celor doua numere "<<endl;
aux.display();
cout<<endl;
cout<<"primul
numar"<<endl;
a.display();
cout<<endl<<"al doilea numar
"<<endl;
b.display();
a=a+b;
cout<<endl<<"primul numar
trece in suma celor doua:"<<endl;
a.display();
cout<<"cel
de al doilea numar ramane
neschimbat "<<endl;
b.display();
getch();
}
Exercitii propuse:
Sa se supraincarce operatorii: -, *, / pentru clasa
complex
Exemplul 2: Supraincarcarea operatorului unar ! se poate utiliza de exemplu pentru a obtine conjugata unui numar complex:
complex operator!()
{complex c;
c.x=x;
c.y=-y;
return c;
}
Apelul se va face astfel:
b=!b;
Sau :
complex q;
q=!b;
Exercitiu propus:
1. Sa se defineasca
o clasa vector care sa contina o metoda de afisare. Sa se determine suma a doi vectori fara a se supraincarca nici un
operator.
2. Aceeasi
problema sa se rezolve prin supratncarcarea
operatorului + si []
Supraincarcarea operatorului de indexare
Operatorul de indexare este un operator binar si are forma
generala:
Tip_vector & operator[](lista_parametri) { prelucrari;
Exemplul 3: }
#include<iostream.h>
#include<conio.h>
class
vector
{public:
float v[20];
int n;
float & operator[](int i) //supraincarcarea
operatorului []
{return v[i];}
vector operator+(vector u);
void afisare();
};
void
vector::afisare()
{for(int i=1;i<=n;i++)
cout<<v[i]<<" ";
cout<<endl;
}
vector vector::operator+(vector u)
{vector rez;
rez.n=n;
for(int i=1;i<=n;i++)
rez.v[i]=v[i]+u.v[i];
return rez;
}
void main()
{clrscr();
vector a,b;
cout<<"nr
de elemente ";
cin>>a.n;
for(int i=1;i<=a.n;i++)
cin>>a[i];
cout<<endl;
cout<<"al doilea vector ";
b.n=a.n;
for( i=1;i<=b.n;i++)
cin>>b[i];
cout<<endl;
cout<<"cei doi vectori sunt
"<<endl;
a.afisare();
cout<<endl;
b.afisare();
vector c;
c=a+b;
cout<<endl<<"suma
"<<endl;
c.afisare();
getch();
}
Exemplul 4:
In mod similar se incarca operatorul ( ) in scopul prelucrarii matricilor:
class matrice
{public:
int a[20][20],nl, nc;
int & operator ( ) (int i,int j)
{return a[i][j]; }
}
Fie matrice m o instanta a clasei complex. Atunci prelucrarea componentei de pe linia 2 si coloana 3 in scopul atribuirii valorii 50 se va face :
m(2,3)=50 ;
Exercitiu propus:
Sa se completeze clasa matrice cu metoda de afisare si sa se supraincarce operatorul +. Sa se determine suma a doua matrici.