Operator jest funkcją więc może zwracać:
- void
- obiekt typu wbudowanego/obiekt klasy przez wartość
- obiekt typu wbudowanego/obiekt klasy przez referencję
- wskaźnik do typu wbudowanego/klasy
To co ma konkretnie zwracać zależy od jego zastosowania i wygody wykorzystania go. Np
Mam klasę A o następującej definicji:
#include <iostream>
using namespace std;
class A
{
public:
int calkowita;
void operator -()
{
if( calkowita < 0 )
{
cout << "Obiekt zawiera w sobie liczbe mniejsza od zera" << endl;
}
else
{
cout << "Obiekt nie zawiera w sobie liczby mniejszej od zera" << endl;
}
}
A() { }
A( int cal )
: calkowita( cal )
{ }
~A() { }
};
int main()
{
A mojObiekt( 88 );
- mojObiekt;
cin.get();
return 0;
}
Chcę aby mój jednoargumentowy operator- działał w taki sposób aby wskazywał mi np. czy w obiekcie klasy A jest obiekt ujemny. Do dalszych etapów wynik tej operacji nie jest mi potrzebny, nie chcę nigdzie go przypisywać itd. Chcę to tylko zobaczyć na ekranie i nic więcej. Decyduję że mój operator ma zwracać void(wolno mi). Chcę również aby mój operator był praktyczny tzn. stawiam go przed obiektem mojej klasy (żadnych innych operacji) i otrzymuję informację jaką chcę. Stąd wymyśliłem definicję tego operatora taką jaką widzisz powyżej.
A teraz zapragnąłem czegoś innego, chcę żeby operato- na obiekty klasy A działał tak że zmienia znak pola calkowity na przeciwny a wynik dzialania zwraca jako osobny obiekt. W tym momencie powinienem go zdefiniować jak?
Musi zwracać obiekt klasy A przez wartość. A jak przez wartość to ja to muszę gdzieś zapisać prawda. Czyli w funkcji main będę potrzebował dodatkowej zmiennej. Więc:
#include <iostream>
using namespace std;
class A
{
public:
int calkowita;
A operator -()
{
A tymczasowy;
tymczasowy.calkowita = - this->calkowita;
return tymczasowy;
}
A() { }
A( int cal )
: calkowita( cal )
{ }
~A() { }
};
int main()
{
A mojObiekt( 88 );
A mojPomocniczyObiekt;
mojPomocniczyObiekt = - mojObiekt;
cout << mojPomocniczyObiekt.calkowita << endl;
cin.get();
return 0;
}
Teraz myślę sobie kurcze jakie to niepraktyczne chciałbym oparatorem - zmieniać trwale znak skladowej całkowitej bez przypisywania do jakiejś pomocniczej zmiennej. Myślę, myślę aha w operatorze wynik zwrócę przez referencję ... do czego ? do obiektu na którym dokonam zmiany znaku więc zmieniam sobie definicję opartora na taką:
#include <iostream>
using namespace std;
class A
{
public:
int calkowita;
A & operator -()
{
this->calkowita = -( this->calkowita );
return * this;
}
A() { }
A( int cal )
: calkowita( cal )
{ }
~A() { }
};
int main()
{
A mojObiekt( 88 );
- mojObiekt;
cout << mojObiekt.calkowita << endl;
cin.get();
return 0;
}
Zobacz jak teraz jest wygodniej. Nie znaczy to że trzeba zawsze zwracać referencję. Zależnie od potrzeby.
A co dodatkowo daje zwracanie referencji. Otóż moge sobie kaskadowo "podziałać" kilka razy z rzędu operatorami '-':
#include <iostream>
using namespace std;
class A
{
public:
int calkowita;
A & operator -()
{
this->calkowita = -( this->calkowita );
return * this;
}
A() { }
A( int cal )
: calkowita( cal )
{ }
~A() { }
};
int main()
{
A mojObiekt( 88 );
- - - - - - - - - - - mojObiekt;
cout << mojObiekt.calkowita << endl;
cin.get();
return 0;
}
Oczywiście jakby zaistniała konieczność to w operatorze sobie moge nawet zwrócić wskaźnik do czegoś... Skompiluj powyższe kody a na pewno zakumasz te operatory. Oczywiście to samo odnosi się do innych operatorów.