JĘZYK C++, FUNKCJE OPERATOROWE 1
Celem ćwiczenia jest zapoznanie z definiowaniem funkcji operatorowych jako funkcji składowych klasy lub funkcji zaprzyjaźnionych oraz ze standardowymi strumieniami wejścia i wyjścia cin i cout.
Wymienione wyżej pojęcia są zilustrowane na przykładzie klasy implementującej strukturę danych typu stos wykorzystywanej w poprzednim ćwiczeniu.
W języku C++ można definiować funkcje określające znaczenie następujących operatorów:
+ - * / % ^ & | ~ !
= < > += -= *= /= %= ^= &=
|= << >> >>= <<= == != <= >= &&
|| ++ -- ->* , -> [] () new delete
Definiując nowe znaczenie wyżej wymienionych operatorów nie można zmieniać składni ani priorytetów tych operatorów. Oznacza to, że nie można przykładowo zdefiniować jednoargumentowego operatora, który standardowo jest dwuargumentowy (np. %) lub odwrotnie (np. !). Nie można też definiować nowych symboli operatorów.
Funkcja operatorowa musi być składową klasy albo mieć co najmniej jeden argument będący klasą lub typem wyliczeniowym (enum). Oznacza to, że definiowane funkcje operatorowe mogą operować na typach zdefiniowanych przez użytkownika. Nie można więc zmieniać standardowego znaczenia operatorów (np. normalnego znaczenia operatorów +, - dla typu int).
Jeśli przykładowo zadeklaruje się następującą klasę:
class M {
// składowe klasy
public :
M operator + (M am);
};
to w programie można użyć następujących konstrukcji:
M m1, m2; // deklaracja obiektów klasy M
m1+m2; // wywołanie funkcji operatorowej operator +
W chwili napotkania wyrażenia m1+m2 kompilator wywoła zdefiniowaną w klasie M funkcję operatorową operator + w następujący sposób:
m1.operator+(m2);
Należy pamiętać, że kompilator nie czyni żadnych założeń co do dodatkowych własności operatorów. Nie można więc założyć, że zdefiniowany przez użytkownika operator + albo * będzie przemienny (tak jak dodawanie czy mnożenie liczb).
Jako przykład niech posłuży definicja funkcji operator *, którego jednym argumentem będzie obiekt typu class M, a drugim liczba całkowita typu int.
Jeżeli funkcję operator* zdefiniować jako funkcję składową klasy (tak jak funkcję operator+ w przykładzie powyżej):
M operator * (int n);
M M::operator * (int n)
{
// definicja funkcji operator *
}
to po odpowiednich deklaracjach, w momencie napotkania wyrażenia (***):
M m1; //deklaracja obiektu klasy M
int k = 3;
m1*k; // wyrażenie (***)
zostanie wywołana funkcja operatorowa m1.operator*(int). Gdyby w programie znalazło się wyrażenia:
k*m1;
to wystąpiłby błąd, ponieważ nie ma możliwości zdefiniowana funkcja operatorowej int.operator*(M) jako funkcji składowej klasy. Problem ten można rozwiązać deklarując klasę M z dwoma operatorowymi funkcjami zaprzyjaźnionymi:
friend M operator * (M m, int n);
friend M operator * (int n, M m);
M operator * (M m, int n)
M operator * (int n, M m)
W takim przypadku kompilator wybierze jedną z funkcji w zależności o typów argumentów po lewej i prawej stronie operatora *.
Do ćwiczenia należy zapoznać się z literatury z następującymi pojęciami:
· funkcje operatorowe i ich definiowanie,
· standardowe strumienie wejścia/wyjścia w języku C++: cin oraz cout.
Z literatury można polecić następujące książki:
· B. Stroustrup „Język C++”,
· S. Lipmann „Podstawy języka C++”.
Na bazie klasy typu Stack zdefiniowanej w poprzednim ćwiczeniu:
Stack & operator << (int Ax); // push()
Stack & operator >> (int &Ax); // pop()
int operator ! (void); // empty()
int operator ~ (void); // full()
Napisać definicje wyżej zadeklarowanych metod operatorowych oraz zastąpić w funkcji main() wywołania metod push(), pop(), empty() i full() odpowiednimi metodami operatorowymi. Uruchomić tę część ćwiczenia jako program nr 1.
friend Stack & operator << (Stack &As, int Ax);
friend Stack & operator >> (Stack &As, int &Ax);
friend int operator ! (Stack As);
friend int operator ~ (Stack As);
Napisać definicje wyżej zadeklarowanych funkcji. Uruchomić tę część ćwiczenia jako program nr 2.
Katedra Automatyki Napędu i Urządzeń Przemysłowych AGH
grzegorj