Przeciążanie operatorów
• Przeciążanie funkcji było omawiane już w
dziale funkcje. Przeciążanymi funkcjami
mogą być także funkcje składowe klasy.
Przeciążaną funkcję można przypisać do
wybranego operatora. Trzeba zaznaczyć, że
nie można przeciążyć następujących
operatorów:
1..
2.?()
3.*
4. ::
Przeciążanie operatorów
• Lista operatorów, które mogą być przeciążane:
+ - * / % ^ & | ~
!
= < > += -= *= /= %= ^=
&=
|= << >> >>= <<= == != <= >=
&&
|| ++ -- , ->* -> new delete
() []
• Operatory
& * - +
mogą być przeciążane w zarówno w wersji
jednoargumentowej jak
i dwuargumentowej.
Przeciążanie operatorów
• Aby przeciążyć operator, należy
utworzyć funkcję o nazwie
składającej się ze słowa kluczowego
operator, po którym będzie
bezpośrednio znajdował się znak
przeciążanego operatora. W
poniższym przykładzie będziemy
przeciążać operator dodawania +:
Przeciążanie operatorów
• #include <iostream.h>
• class add_char
• {
• private:
• char c;
• public:
• add_char(char c_in) { c = c_in; } //konstruktor
• char operator+(add_char& c2); //przeciążony operator +
• char c_pr() { return(c); }
• };
Przeciążanie operatorów
• int main()
• {
• add_char c1('g');
• add_char c2('h');
• char sum;
• sum = c1+ c2;
• cout << "'Suma' " << c1.c_pr() << " i " << c2.c_pr() << "
równa się " << sum << "\n"; return(0);
• }
Przeciążanie operatorów
• char add_char::operator+(add_char&
c2)
• { return(c +(c2.c - ('a' - 1))); /*
dodaje do znaku c1 alfabetyczne
przesunięcie znaku c2 */
• }
Przeciążanie operatorów
• Nawet przy przeciążonych operatorach stosowane są
zwykłe reguły pierwszeństwa i kojarzenia. Dlatego bez
względu na to, jak przeciążymy operatory + i *, działanie:
• a + b * c powinno zawsze być oceniane jako: a + (b * c) Nie
można przeciążyć podstawowego operatora, który jest
wyłącznie jednoargumentowy lub dwuargumentowy, tak
aby miał przeciwne znaczenie. W przeciążonych
operatorach powinniśmy naśladować zastosowanie
równoważnego operatora podstawowego, aby jego
zastosowanie było intuicyjne. Nie powinno się przeciążać
operatora + tak aby odejmował gdyż może to prowadzić do
wielu błędów i niejasności.
Przeciążanie operatorów
• Operator >> jest przeciążony dla następujących
typów:
• char*
• char&
• int&, long&, short&
• unsigned (wszystkie poprzednie)
• bool&
• float&
• double&
• long double&
• streambuf* (będzie opisany później)
• <manipulatory> (również później)
Przykład
• #include<iostream>
• class zespolona
// deklaracja klasy
• {
•
double re, im;
• public:
• zespolona ( ) {re = 0; im = 0; }
• zespolona (double r, double i): re(r), im(i) { }
• // konstruktor
• zespolona operator + (zespolona z);
• zespolona operator * ( );
• zespolona operator / (zespolona z);
•
/* deklaracje operatorów przeciążonych */
• friend zespolona operator - (zespolona z1, zespolona z2);
• friend ostream& operator << (ostream& wyjscie, zespolona z);
• friend istream& operator >> (istream& wejscie, zespolona &z);
zespolona zespolona :: operator * ( )
{
return zespolona (re, -im);
}
zespolona zespolona::operator + (zespolona z)
{
return zespolona (re+z.re, im+z.im);
}
zespolona operator-(zespolona z1, zespolona z2)
{
return zespolona(z1.re-z2.re, z1.im-z2.im);
}
zespolona zespolona ::operator /(zespolona z)
{
return zespolona(re/z.re,im/z.im);
}
ostream& operator <<(ostream& wyjscie, zespolona z)
{
return wyjscie <<'(' <<z.re<<",j"<<z.im<<')';
}
istream& operator >>(istream& wejscie, zespolona &z)
{
cout<<"re: ";
wejscie>>z.re;
cout<<"im: ";
wejscie>>z.im;
return wejscie;
}
void main ( )
{
zespolona z, z1(12, 22), z2 (5.5, -6), z3;
cout<<"\t Mamy podane nastepujace liczby zespolone:"<<endl;
cout<<"\n z1= "<<z1<<endl;
cout<<" z2= "<<z2<<endl<<endl;
cout<<"\tPodaj nowa liczbe zespolona"<<endl;
cin>>z3;
cout<<"\n z3= "<<z3<<endl<<endl;
cout<<"\tWykonujemy operacje matematyczne"<<endl;
cout<<"\n z= z1+ z3" ;
z=z1+z3;
cout<<"\t z= "<<z<<endl;
// operator +
cout<<"\n z= z2- z1";
z=z2-z1;
cout<<"\t z= "<<z<<endl;
// operator -
cout<<" \n z= *z2";
z=*z2; cout<<"\t\t z= "<<z<<endl; // operator *
cout<<"\n z= (z2+ z3)- z1" ;
z=z2+z3-z1;
cout<<" z= "<<z<<endl;
cout<<"\n z= z1/ z3" ;
// operator /
z=z1/z3;
cout<<"\t z= "<<z<<endl;
cout<<endl;
}