Jak już wiemy wyrażenie
double x=2;jest poprawne, mimo, że 2 jest typu int a nie double. Powoduje ono wywołanie automatycznej konwersji liczby 2 na typ double, a następnie przypisanie wyniku na x.
Możliwe jest zdefiniowanie takich konwersji przez użytkownika. Zmienne jednego typu (nazwijmy go T1) są konwertowane na inny (T2) w dwóch przypadkach:
Przykład: Oto przykład klasy, której obiektami są liczby zespolone:
class Zespolona {Teraz kod
public:
Zespolona(): re(0), im(0) {};
Zespolona(double _re): re(_re), im(0) {};
Zespolona(double _re, double _im): re(_re), im(_im) {};
operator double() {return re;};
void wypisz() { cout << re << "+" << im << "i"; };
private:
double re, im;
};
Zespolona z=5.5;powoduje wypisanie 5.5+0i (wywołany zostaje konstruktor Zespolona(double), który zamienia wartość 5.5 typu double na typ Zespolona. Natomiast kod
z.wypisz();
Zespolona z(3,1);powoduje wypisanie liczby 3 - z zostaje zamieniona na typ double przy pomocy metody operator double.
double n=z;
cout << n;
class Zespolona {a następnie jej użyć np. w następujący sposób:
public:
...
Zespolona suma(Zespolona z) { return Zespolona(re+z.re, im+z.im); }
...
};
Zespolona z1(2,1);Nie jest to zbyt wygodny sposób, szczególnie gdy chcemy obliczać bardziej skomplikowane wyrażenia. Na szczęscie C++ umożliwia zdefiniowanie standardowych operatorów dla zdefiniowanych typów danych. Możemy to zrobić na jeden z dwóch sposobów:
Zespolona z2=5.5;
Zespolona z3=z1.dodaj(z2);
class Zespolona {
public:
...
Zespolona operator+(Zespolona z) { return Zespolona(re+z.re, im+z.im); }
...
};
Zespolona operator+(Zespolona z1, Zespolona z2);
Jeśli zdefiniujemy operator + na jeden z tych sposobów (nie należy używać obydwu, gdyż spowoduje to błąd), możemy dodawać liczby zespolone tak jak całkowite, np. można napisać
Zespolona z1(2,1);lub nawet
Zespolona z2=5.5;
Zespolona z3=z1+z2;
Zespolona z3=Zespolona(2,1)+5.5;(w tym przypadku zostaną zastosowane zarówno konwersje jak i operator +).
Uwagi:
Zespolona z3=5.5+Zespolona(2,1);nie będzie poprawny - 5.5 jest typu double i nie może posiadać metody operator+ (zresztą żadnej metody). Jeśli zaś zdefiniowana będzie funkcja
Zespolona operator+(Zespolona z1, Zespolona z2);wszystko obliczy się poprawnie.
Zespolona operator+(Zespolona z1, Zespolona z2) {nie jest dobra, gdyż odwołuje się do pól prywatnych re oraz im. Staje się ona poprawna po zadeklarowaniu jej jako funkcji zaprzyjaźnionej dla klasy Zespolona poprzez umieszczenie linijki
return Zespolona(z1.re+z2.re, z1.im+z2.im);
}
friend Zespolona operator+(Zespolona z1, Zespolona z2);w ciele klasy.