Programowanie strukturalne i obiektowe C++ Przeładowanie operatorów Robert Nowak
Przykład programu 1 #include using namespace std; class ulamek { public: int licznik; int mianownik; ulamek () {licznik=1; mianownik=1;} ulamek (int l, int m); void wypisz () { cout <<licznik<<"/"<<mianownik; } void skracaj (); };
Ciąg dalszy programu 1 ulamek:: ulamek (int l, int m) { licznik=l; if (m!=0) mianownik=m; else cout <<"Mianownik nie moze miec wartosci 0\n"; } void ulamek:: skracaj () { int a=abs(licznik); int b=abs(mianownik); while (a!=b) if (a-b>0) a=a-b; else b=b-a; licznik=licznik/a; mianownik=mianownik/a; }
Ciąg dalszy programu 1 ulamek pomnoz (ulamek u_1, ulamek u_2) { ulamek u_3; u_3.licznik=u_1.licznik*u_2.licznik; u_3.mianownik=u_1.mianownik*u_2.mianownik; return u_3; } ulamek podziel (ulamek u_1, ulamek u_2) { ulamek u_3; u_3.licznik=u_1.licznik*u_2.mianownik; u_3.mianownik=u_1.mianownik*u_2.licznik; return u_3; }
Ciąg dalszy programu 1 ulamek dodaj (ulamek u_1, ulamek u_2) { ulamek u_3; int a=abs(u_1.mianownik); int b=abs(u_2.mianownik); int c=a,d=b; while (a!=b) if (a-b>0) a=a-b; else b=b-a; int nww=(c*d) / a; u_3.mianownik=nww; u_3.licznik=nww/c*u_1.licznik+nww/d*u_2.licznik; return u_3; }
Ciąg dalszy programu 1 ulamek odejmij (ulamek u_1, ulamek u_2) { ulamek u_3; int a=abs(u_1.mianownik); int b=abs(u_2.mianownik); int c=a,d=b; while (a!=b) if (a-b>0) a=a-b; else b=b-a; int nww=(c*d) / a; u_3.mianownik=nww; u_3.licznik=nww/c*u_1.licznik-nww/d*u_2.licznik; return u_3; }
Ciąg dalszy programu 1 main () { int licz, mian,r; ulamek ul1 (4,5); ulamek ul2 (1,7); cout << "Pierwszy ulamek: "; ul1.wypisz (); cout <<'\n'<< "Po skroceniu: "; ul1.skracaj (); ul1.wypisz (); cout <<'\n'<<"Drugi ulamek: "; ul2.wypisz (); cout <<'\n'<< "Po skroceniu: "; ul2.skracaj (); ul2.wypisz (); ulamek ul5=pomnoz(ul1,ul2); cout <<'\n'<<"Wynik mnozenia u1*u2 wynosi:"; ul5.wypisz(); cout <<'\n'<< "Po skroceniu: "; ul5.skracaj (); ul5.wypisz ();
Ciąg dalszy programu 1 ul5=podziel(ul1,ul2); cout <<'\n'<<"Wynik dzielenia u1/u2 wynosi:"; ul5.wypisz(); cout <<'\n'<< "Po skroceniu: "; ul5.skracaj (); ul5.wypisz (); ul5=podziel(ul2,ul1); cout <<'\n'<<"Wynik dzielenia u2/u1 wynosi:"; ul5.wypisz(); cout <<'\n'<< "Po skroceniu: "; ul5.skracaj (); ul5.wypisz (); ul5=dodaj(ul1,ul2); cout <<'\n'<<"Wynik dodawania u1+u2 wynosi:"; ul5.wypisz(); cout <<'\n'<< "Po skroceniu: "; ul5.skracaj (); ul5.wypisz (); ul5=odejmij(ul1,ul2); cout <<'\n'<<"Wynik odejmowania u1-u2 wynosi:"; ul5.wypisz(); cout <<'\n'<< "Po skroceniu: "; ul5.skracaj (); ul5.wypisz ();
Ciąg dalszy programu 1 cout <<'\n'<<"Podaj licznik swojego ulamka 3: "; cin>>licz; cin.ignore(); do {cout <<"Podaj mianownik swojego ulamka 3: "; cin>>mian; cin.ignore(); }while (mian==0); ulamek ul3 (licz,mian); cout <<"Podaj licznik swojego ulamka 4: "; cin>>licz; cin.ignore(); do {cout <<"Podaj mianownik swojego ulamka 4: "; cin>>mian; cin.ignore(); }while (mian==0); ulamek ul4 (licz,mian);
Ciąg dalszy programu 1 cout <<'\n'<<"Twoj ulamek 3: "; ul3.wypisz (); cout <<'\n'<< "Po skroceniu: "; ul3.skracaj (); ul3.wypisz (); cout <<'\n'<<"Twoj ulamek 4: "; ul4.wypisz (); cout <<'\n'<< "Po skroceniu: "; ul4.skracaj (); ul4.wypisz (); ul5=pomnoz(ul3,ul4); cout <<'\n'<<"Wynik mnozenia u3*u4 wynosi:"; ul5.wypisz(); cout <<'\n'<< "Po skroceniu: "; ul5.skracaj (); ul5.wypisz (); ul5=podziel(ul3,ul4); cout <<'\n'<<"Wynik dzielenia u3/u4 wynosi:"; ul5.wypisz(); cout <<'\n'<< "Po skroceniu: "; ul5.skracaj (); ul5.wypisz ();
Ciąg dalszy programu 1 ul5=podziel(ul4,ul3); cout <<'\n'<<"Wynik dzielenia u4/u3 wynosi:"; ul5.wypisz(); cout <<'\n'<< "Po skroceniu: "; ul5.skracaj (); ul5.wypisz (); ul5=dodaj(ul3,ul4); cout <<'\n'<<"Wynik dodawania u3+u4 wynosi:"; ul5.wypisz(); cout <<'\n'<< "Po skroceniu: "; ul5.skracaj (); ul5.wypisz (); ul5=odejmij(ul3,ul4); cout <<'\n'<<"Wynik odejmowania u3-u4 wynosi:"; ul5.wypisz(); cout <<'\n'<< "Po skroceniu: "; ul5.skracaj (); ul5.wypisz (); cout <<"\n\n"<<"Nacisnij ENTER aby zakonczyc..."; getchar (); return 0; }
Przykład programu 2 #include using namespace std; class ulamek { int licznik; int mianownik; public: ulamek () {licznik=1; mianownik=1; } ulamek (int l, int m); void wypisz () { cout <<licznik<<"/"<<mianownik; } void skracaj (); ulamek pomnoz (ulamek u_2); ulamek podziel (ulamek u_2); ulamek dodaj (ulamek u_2); ulamek odejmij (ulamek u_2); };
Ciąg dalszy programu 2 ulamek:: ulamek (int l, int m) {licznik=l; if (m!=0) mianownik=m; else cout <<"Mianownik nie moze miec wartosci 0\n";} void ulamek:: skracaj () { int a=abs(licznik); int b=abs(mianownik); while (a!=b) if (a-b>0) a=a-b; else b=b-a; licznik=licznik/a; mianownik=mianownik/a;}
Ciąg dalszy programu 2 ulamek ulamek:: pomnoz (ulamek u_2) { ulamek u_3; u_3.licznik=this->licznik*u_2.licznik; u_3.mianownik=this->mianownik*u_2.mianownik; return u_3; } ulamek ulamek:: podziel (ulamek u_2) { ulamek u_3; u_3.licznik=this->licznik*u_2.mianownik; u_3.mianownik=this->mianownik*u_2.licznik; return u_3; }
Ciąg dalszy programu 2 ulamek ulamek:: dodaj (ulamek u_2) { ulamek u_3; int a=abs(this->mianownik); int b=abs(u_2.mianownik); int c=a,d=b; while (a!=b) if (a-b>0) a=a-b; else b=b-a; int nww=(c*d) / a; u_3.mianownik=nww; u_3.licznik=nww/c*this->licznik+nww/d*u_2.licznik; return u_3; }
Ciąg dalszy programu 2 ulamek ulamek:: odejmij (ulamek u_2) { ulamek u_3; int a=abs(this->mianownik); int b=abs(u_2.mianownik); int c=a,d=b; while (a!=b) if (a-b>0) a=a-b; else b=b-a; int nww=(c*d) / a; u_3.mianownik=nww; u_3.licznik=nww/c*this->licznik-nww/d*u_2.licznik; return u_3; }
Ciąg dalszy programu 2 main () { int licz, mian,r; ulamek ul1 (4,5); ulamek ul2 (1,7); cout << "Pierwszy ulamek: "; ul1.wypisz (); cout <<'\n'<< "Po skroceniu: "; ul1.skracaj (); ul1.wypisz (); cout <<'\n'<<"Drugi ulamek: "; ul2.wypisz (); cout <<'\n'<< "Po skroceniu: "; ul2.skracaj (); ul2.wypisz (); ulamek ul5=ul1.pomnoz(ul2); cout <<'\n'<<"Wynik mnozenia u1*u2 wynosi:"; ul5.wypisz(); cout <<'\n'<< "Po skroceniu: "; ul5.skracaj (); ul5.wypisz ();
Ciąg dalszy programu 2 ul5=ul1.podziel(ul2); cout <<'\n'<<"Wynik dzielenia u1/u2 wynosi:"; ul5.wypisz(); cout <<'\n'<< "Po skroceniu: "; ul5.skracaj (); ul5.wypisz (); ul5=ul2.podziel(ul1); cout <<'\n'<<"Wynik dzielenia u2/u1 wynosi:"; ul5.wypisz(); cout <<'\n'<< "Po skroceniu: "; ul5.skracaj (); ul5.wypisz (); cout <<'\n'<<"Podaj licznik swojego ulamka 3: "; cin>>licz; cin.ignore(); do { cout <<"Podaj mianownik swojego ulamka 3: "; cin>>mian; cin.ignore(); }while (mian==0); ulamek ul3 (licz,mian);
Ciąg dalszy programu 2 cout <<"Podaj licznik swojego ulamka 4: "; cin>>licz; cin.ignore(); do { cout <<"Podaj mianownik swojego ulamka 4: "; cin>>mian; cin.ignore(); }while (mian==0); ulamek ul4 (licz,mian); cout <<'\n'<<"Twoj ulamek 3: "; ul3.wypisz (); cout <<'\n'<< "Po skroceniu: "; ul3.skracaj (); ul3.wypisz (); cout <<'\n'<<"Twoj ulamek 4: "; ul4.wypisz (); cout <<'\n'<< "Po skroceniu: "; ul4.skracaj (); ul4.wypisz ();
Ciąg dalszy programu 2 ul5=ul3.pomnoz(ul4); cout <<'\n'<<"Wynik mnozenia u3*u4 wynosi:"; ul5.wypisz(); cout <<'\n'<< "Po skroceniu: "; ul5.skracaj (); ul5.wypisz (); ul5=ul3.podziel(ul4); cout <<'\n'<<"Wynik dzielenia u3/u4 wynosi:"; ul5.wypisz(); cout <<'\n'<< "Po skroceniu: "; ul5.skracaj (); ul5.wypisz (); ul5=ul4.podziel(ul3); cout <<'\n'<<"Wynik dzielenia u4/u3 wynosi:"; ul5.wypisz(); cout <<'\n'<< "Po skroceniu: "; ul5.skracaj (); ul5.wypisz (); ul5=ul3.dodaj(ul4);
Ciąg dalszy programu 2 cout <<'\n'<<"Wynik dodawania u3+u4 wynosi:"; ul5.wypisz(); cout <<'\n'<< "Po skroceniu: "; ul5.skracaj (); ul5.wypisz (); ul5=ul3.odejmij(ul4); cout <<'\n'<<"Wynik odejmowania u3-u4 wynosi:"; ul5.wypisz(); cout <<'\n'<< "Po skroceniu: "; ul5.skracaj (); ul5.wypisz (); cout <<"\n\n"<<"Nacisnij ENTER aby zakonczyc..."; getchar (); return 0; }
Wstęp Projektując klasę możemy zadbać o to, by pewne operacje na obiektach tej klasy wykonywane były na zasadzie przeładowania operatorów. Mówiąc najkrócej w tej części zajmiemy się tym, jak sprawić by znaczki takie jak: ‘+’, ‘-’ itd. pracowały dla nas i robiły to, co my im każemy. Sam znaczek ‘+’ nie dodaje dwóch liczb. Kiedy on występuje w tekście programu, kompilator wywołuje specjalną funkcję, która zajmuje się dodawaniem liczb. Nazwijmy tę funkcję operatorem dodawania.
Zasady przeładowania operatorów Przeładowania operatora dokonuje się definiując swoją własną funkcję która: nazywa się oznacza symbol operatora który przeładowujemy np.: +, -, *, itd.) co najmniej jeden z argumentów jest obiektem danej klasy (musi być obiekt, nie wskaźnik do obiektu)
Definicja przeładowanego operatora typ_zwracany (argumenty) { //ciało funkcji }
Operatory które można przeładować Przeładować możemy operatory: Przy czym operatory & * - + możemy przeładować zarówno w wersji jedno jak i dwuargumentowej. Operator można przeładować wielokrotnie. +-*/%^&|~! =<>+=-=*=/=%=^=&= |=<<>>>>=<<===!=<=>=&& ||++--, -> * -> newdelete()[ ]
Operatory predefiniowane Operatory które są automatycznie generowane dla każdej klasy. Są to: „ = ” - operator przypisania do obiektu danej klasy „ & ” - (jednoargumentowy) pobranie adresu obiektu „, ” - znaczenie identyczne jak dla typów wbudowanych „ new ”, „ delete ” – kreacja i likwidacja obiektów Można zdefiniować własną wersję tych operatorów (nie ma sposobu aby zrezygnować z predefinicji)
Operatory dwuargumentowe Operatory dwuargumentowe możemy przeładować na dwa sposoby: jako funkcję składową wywoływaną z jednym argumentem – jako funkcje nieskładową wywoływaną z dwoma argumentami y) Taka funkcja operatorowa zostanie automatycznie wywołana gdy obok znaczka danego operatora znajdą się dwa argumenty określonego przez nas typu y)
Operatory dwuargumentowe Funkcja operatorowa która jest składową klasy wymaga aby obiekt stojący po lewej stronie operatora był obiektem tej klasy. Tego ograniczenie nie ma operator który jest zwykłą funkcją globalną. Operatory = [ ] ( ) -> muszą być funkcjami składowymi klasy.
Funkcja operatorowa jako funkcja składowa Funkcja operatorowa może być zwykłą, globalną funkcją, a może być także funkcją składową klasy. Jeśli operator definiujemy jako funkcję składową, to ma ona zawsze o jeden argument mniej niż ta sama funkcja napisana w postaci funkcji globalnej. Ten „brakujący” argument – w wypadku funkcji składowej – spowodowany jest oczywiście istnieniem wskaźnika this.
Czy funkcja operatorowa musi być przyjacielem klasy? Jeśli funkcja operatorowa ma pracować tylko na publicznych składnikach klasy, to może być ona zwykłą funkcją składową, bez żadnych specjalnych uprawnień. Jeśli chcemy, by operator mógł pracować także na niepublicznych składnikach klasy – wówczas klasa musi zadeklarować tę funkcję operatorową jako zaprzyjaźnioną. Przyjaźń nie jest obowiązkowa. To przecież oczywiste – jeśli operator ma np.: zagwizdać na cześć obiektu danej klasy, to do tego nie jest mu potrzebny dostęp do jej prywatnych składników
Przykład programu 3 #include using namespace std; class ulamek {int licznik; int mianownik; public: ulamek () {licznik=1; mianownik=1; } ulamek (int l, int m); void wypisz () { cout <<licznik<<"/"<<mianownik; } void skracaj (); ulamek operator* (ulamek u_2); ulamek operator/ (ulamek u_2); ulamek operator+ (ulamek u_2); ulamek operator- (ulamek u_2); };
Ciąg dalszy programu 3 ulamek:: ulamek (int l, int m) {licznik=l; if (m!=0) mianownik=m; else cout <<"Mianownik nie moze miec wartosci 0\n";} void ulamek:: skracaj () { int a=abs(licznik); int b=abs(mianownik); while (a!=b) if (a-b>0) a=a-b; else b=b-a; licznik=licznik/a; mianownik=mianownik/a; }
Ciąg dalszy programu 3 ulamek ulamek:: operator* (ulamek u_2) { ulamek u_3; u_3.licznik=this->licznik*u_2.licznik; u_3.mianownik=this->mianownik*u_2.mianownik; return u_3; } ulamek ulamek:: operator/ (ulamek u_2) { ulamek u_3; u_3.licznik=this->licznik*u_2.mianownik; u_3.mianownik=this->mianownik*u_2.licznik; return u_3; }
Ciąg dalszy programu 3 ulamek ulamek:: operator+ (ulamek u_2) { ulamek u_3; int a=abs(this->mianownik); int b=abs(u_2.mianownik); int c=a,d=b; while (a!=b) if (a-b>0) a=a-b; else b=b-a; int nww=(c*d) / a; u_3.mianownik=nww; u_3.licznik=nww/c*this->licznik+nww/d*u_2.licznik; return u_3; }
Ciąg dalszy programu 3 ulamek ulamek:: operator- (ulamek u_2) { ulamek u_3; int a=abs(this->mianownik); int b=abs(u_2.mianownik); int c=a,d=b; while (a!=b) if (a-b>0) a=a-b; else b=b-a; int nww=(c*d) / a; u_3.mianownik=nww; u_3.licznik=nww/c*this->licznik-nww/d*u_2.licznik; return u_3; }
Ciąg dalszy programu 3 main () { int licz, mian,r; ulamek ul1 (4,5); ulamek ul2 (1,7); cout << "Pierwszy ulamek: "; ul1.wypisz (); cout <<'\n'<< "Po skroceniu: "; ul1.skracaj (); ul1.wypisz (); cout <<'\n'<<"Drugi ulamek: "; ul2.wypisz (); cout <<'\n'<< "Po skroceniu: "; ul2.skracaj (); ul2.wypisz (); ulamek ul5=ul1*ul2; cout <<'\n'<<"Wynik mnozenia u1*u2 wynosi:"; ul5.wypisz(); cout <<'\n'<< "Po skroceniu: "; ul5.skracaj (); ul5.wypisz ();
Ciąg dalszy programu 3 ul5=ul1/ul2; cout <<'\n'<<"Wynik dzielenia u1/u2 wynosi:"; ul5.wypisz(); cout <<'\n'<< "Po skroceniu: "; ul5.skracaj (); ul5.wypisz (); ul5=ul2/ul1; cout <<'\n'<<"Wynik dzielenia u2/u1 wynosi:"; ul5.wypisz(); cout <<'\n'<< "Po skroceniu: "; ul5.skracaj (); ul5.wypisz (); ul5=ul1+ul2; cout <<'\n'<<"Wynik dodawania u1+u2 wynosi:"; ul5.wypisz(); cout <<'\n'<< "Po skroceniu: "; ul5.skracaj (); ul5.wypisz (); ul5=ul1-ul2; cout <<'\n'<<"Wynik odejmowania u1-u2 wynosi:"; ul5.wypisz(); cout <<'\n'<< "Po skroceniu: "; ul5.skracaj (); ul5.wypisz ();
Ciąg dalszy programu 3 cout <<'\n'<<"Podaj licznik swojego ulamka 3: "; cin>>licz; cin.ignore(); do { cout <<"Podaj mianownik swojego ulamka 3: "; cin>>mian; cin.ignore(); }while (mian==0); ulamek ul3 (licz,mian); cout <<"Podaj licznik swojego ulamka 4: "; cin>>licz; cin.ignore(); do { cout <<"Podaj mianownik swojego ulamka 4: "; cin>>mian; cin.ignore(); }while (mian==0); ulamek ul4 (licz,mian);
Ciąg dalszy programu 3 cout <<'\n'<<"Twoj ulamek 3: "; ul3.wypisz (); cout <<'\n'<< "Po skroceniu: "; ul3.skracaj (); ul3.wypisz (); cout <<'\n'<<"Twoj ulamek 4: "; ul4.wypisz (); cout <<'\n'<< "Po skroceniu: "; ul4.skracaj (); ul4.wypisz (); ul5=ul3*ul4; cout <<'\n'<<"Wynik mnozenia u3*u4 wynosi:"; ul5.wypisz(); cout <<'\n'<< "Po skroceniu: "; ul5.skracaj (); ul5.wypisz (); ul5=ul3/ul4; cout <<'\n'<<"Wynik dzielenia u3/u4 wynosi:"; ul5.wypisz(); cout <<'\n'<< "Po skroceniu: "; ul5.skracaj (); ul5.wypisz ();
Ciąg dalszy programu 3 ul5=ul4/ul3; cout <<'\n'<<"Wynik dzielenia u4/u3 wynosi:"; ul5.wypisz(); cout <<'\n'<< "Po skroceniu: "; ul5.skracaj (); ul5.wypisz (); ul5=ul3+ul4; cout <<'\n'<<"Wynik dodawania u3+u4 wynosi:"; ul5.wypisz(); cout <<'\n'<< "Po skroceniu: "; ul5.skracaj (); ul5.wypisz (); ul5=ul3-ul4; cout <<'\n'<<"Wynik odejmowania u3-u4 wynosi:"; ul5.wypisz(); cout <<'\n'<< "Po skroceniu: "; ul5.skracaj (); ul5.wypisz (); cout <<"\n\n"<<"Nacisnij ENTER aby zakonczyc..."; getchar (); return 0; }