Wstep do Programowania 2
Transkrypt
Wstep do Programowania 2
Wstep ˛ do Programowania 2 dr Bożena Woźna-Szcześniak [email protected] Akademia im. Jana Długosza Wykład 6 Klasa Time przed przeciażeniem ˛ operatorów # i f n d e f MYTIME0_H_ # d e f i n e MYTIME0_H_ c l a s s Time { private : i n t hours ; i n t minutes ; public : Time ( ) ; Time ( i n t h , i n t m = 0 ) ; v o i d AddMin ( i n t m) ; v o i d AddHr ( i n t h ) ; v o i d Reset ( i n t h = 0 , i n t m = 0 ) ; Time Sum( c o n s t Time & t ) c o n s t ; v o i d Show ( ) c o n s t ; }; #endif mytime0.cpp - cz.1 #include <iostream> #include "mytime0.h" Time::Time() { hours = minutes = 0; } Time::Time(int h, int m) { hours = h; minutes = m; } void Time::AddMin(int m) { minutes += m; hours += minutes / 60; minutes %= 60; } void Time::AddHr(int h) { hours += h; } mytime0.cpp - cz.2 void Time::Reset(int h, int m) { hours = h; minutes = m; } Time Time::Sum(const Time & t) const { Time sum; sum.minutes = minutes + t.minutes; sum.hours = hours + t.hours + sum.minutes / 60; sum.minutes %= 60; return sum; } void Time::Show() const { std::cout << hours << " godzin, " << minutes << " minut"; } Program wykonawczy # i n c l u d e < iostream > # i n c l u d e " mytime0 . h " i n t main ( ) { using std : : cout ; using std : : endl ; Time p l a n n i n g , coding ( 2 , 4 0 ) , f i x i n g ( 5 , 5 5 ) , t o t a l ; c o u t << " czas planowania = " ; p l a n n i n g . Show ( ) ; c o u t << e n d l ; c o u t << " czas kodowania = " ; coding . Show ( ) ; c o u t << e n d l ; c o u t << " czas p o p r a w i a n i a = " ; f i x i n g . Show ( ) ; c o u t << e n d l ; t o t a l = coding .Sum( f i x i n g ) ; c o u t << " Lacznie ( coding .Sum( f i x i n g ) ) = " ; t o t a l . Show ( ) ; c o u t << e n d l ; return 0; } Wykonanie czas planowania = 0 godzin, 0 minut czas kodowania = 2 godzin, 40 minut czas poprawiania = 5 godzin, 55 minut Lacznie (coding.Sum(fixing)) = 8 godzin, 35 minut Uzupełnienie klasy Time o operator dodawania # i f n d e f MYTIME1_H_ # d e f i n e MYTIME1_H_ c l a s s Time { private : i n t hours ; i n t minutes ; public : Time ( ) ; Time ( i n t h , i n t m = 0 ) ; v o i d AddMin ( i n t m) ; v o i d AddHr ( i n t h ) ; v o i d Reset ( i n t h = 0 , i n t m = 0 ) ; Time o p e r a t o r +( c o n s t Time & t ) c o n s t ; v o i d Show ( ) c o n s t ; }; #endif mytime1.cpp - operator++ #include <iostream> #include "mytime1.h" ... Time Time::operator+(const Time & t) const { Time sum; sum.minutes = minutes + t.minutes; sum.hours = hours + t.hours + sum.minutes / 60; sum.minutes %= 60; return sum; } ... Program wykonawczy # i n c l u d e < iostream > # i n c l u d e " mytime1 . h " u s i n g namespace s t d ; i n t main ( ) { Time p l a n n i n g , coding ( 2 , 4 0 ) , f i x i n g ( 5 , 5 5 ) , t o t a l ; c o u t << " czas planowania = " ; p l a n n i n g . Show ( ) ; c o u t << e n d l ; c o u t << " czas kodowania = " ; coding . Show ( ) ; c o u t << e n d l ; c o u t << " czas p o p r a w i a n i a = " ; f i x i n g . Show ( ) ; c o u t << e n d l ; t o t a l = coding + f i x i n g ; c o u t << " Lacznie ( coding + f i x i n g ) = " ; t o t a l . Show ( ) ; c o u t << e n d l ; Time m o r e f i x i n g ( 3 , 2 8 ) ; c o u t << " k o l e j n e poprawki = " ; m o r e f i x i n g . Show ( ) ; c o u t << e n d l ; t o t a l = m o r e f i x i n g . o p e r a t o r +( t o t a l ) ; / / z a p i s f u n k c y j n y c o u t << " Lacznie ( m o r e f i x i n g . o p e r a t o r +( t o t a l ) ) = " ; t o t a l . Show ( ) ; c o u t << e n d l ; return 0; } Wykonanie czas planowania = 0 godzin, 0 minut czas kodowania = 2 godzin, 40 minut czas poprawiania = 5 godzin, 55 minut Lacznie (coding + fixing) = 8 godzin, 35 minut kolejne poprawki = 3 godzin, 28 minut Lacznie (morefixing.operator+(total)) = 12 godzin, 3 minut Ograniczenia przy przeciażaniu ˛ operatorów Przynjamniej jeden z operandów (argumentów) przeciażanego ˛ operatora musi być typu niestandardowego (tj. zdefiniowanego przez użytkownika). Nie można przeciażać ˛ operatora w sposób, który naruszałby jego składnie˛ (np. opeartora dwuargumentowego nie można traktować jako jednoargumentowy). Nie można tworzyć nowych symboli operatorów. Nie można przeciażać ˛ nastepuj ˛ acych ˛ operatorów: przynależności - ., wskaźnika do składowej .*, zakresu - ::, warunkowego - ?:, operatorów rzutowania typów. Ograniczenia przy przeciażaniu ˛ operatorów Operatory które można przeciażać ˛ tylko przy pomocy metod klasy: operator przypisania - = operator wywołania funkcji - () operator indeksowania - [] operator wskaźnikowego dostepu ˛ do składowej klasy -> Pozostałe operatory można przeciażać ˛ zarówno przy pomocy metod klasy jak i przy pomocy funkcji zaprzyjaźnionych. Wiecej ˛ przeciażonych ˛ operatorów # i f n d e f MYTIME2_H_ # d e f i n e MYTIME2_H_ c l a s s Time { private : i n t hours ; i n t minutes ; public : Time ( ) ; Time ( i n t h , i n t m = 0 ) ; v o i d AddMin ( i n t m) ; v o i d AddHr ( i n t h ) ; v o i d Reset ( i n t h = 0 , i n t m = 0 ) ; Time o p e r a t o r +( c o n s t Time & t ) c o n s t ; Time o p e r a t o r −( c o n s t Time & t ) c o n s t ; Time o p e r a t o r ∗ ( double n ) c o n s t ; v o i d Show ( ) c o n s t ; }; #endif mytime2.cpp - operator - #include <iostream> #include "mytime2.h" ... Time Time::operator-(const Time & t) const { Time diff; int tot1, tot2; tot1 = t.minutes + 60 * t.hours; tot2 = minutes + 60 * hours; diff.minutes = (tot2 - tot1) % 60; diff.hours = (tot2 - tot1) / 60; return diff; } ... mytime2.cpp - operator * #include <iostream> #include "mytime2.h" ... Time Time::operator*(double mult) const { Time result; long totalminutes = hours * mult * 60 + minutes * mult; result.hours = totalminutes / 60; result.minutes = totalminutes % 60; return result; } ... Program wykonawczy # i n c l u d e < iostream > # i n c l u d e " mytime2 . h " u s i n g namespace s t d ; i n t main ( ) { Time weeding ( 4 , 3 5 ) , waxing ( 2 , 4 7 ) , t o t a l , d i f f , a d j u s t e d ; c o u t << " czas p i e l e n i a = " ; weeding . Show ( ) ; c o u t << e n d l ; c o u t << " czas woskowania = " ; waxing . Show ( ) ; c o u t << e n d l ; c o u t << " Laczny czas pracy = " ; t o t a l = weeding + waxing ; / / zastosowanie o p e r a t o r a o p e r a t o r + ( ) t o t a l . Show ( ) ; c o u t << e n d l ; d i f f = weeding − waxing ; / / zastosowanie o p e r a t o r a o p e r a t o r −() c o u t << " czas p i e l e n i a − czas woskowania = " ; d i f f . Show ( ) ; c o u t << e n d l ; adjusted = t o t a l ∗ 1. 5; / / zastosowanie o p e r a t o r a o p e r a t o r ∗ ( ) c o u t << " czas pracy z poprawka na przerwy = " ; a d j u s t e d . Show ( ) ; c o u t << e n d l ; return 0; } Wykonanie czas pielenia = 4 godzin, 35 minut czas woskowania = 2 godzin, 47 minut Laczny czas pracy = 7 godzin, 22 minut czas pielenia - czas woskowania = 1 godzin, 48 minut czas pracy z poprawka na przerwy = 11 godzin, 3 minut Funkcje zaprzyjaźnione Zaprzyjaźniajac ˛ funkcje˛ z określona˛ klasa, ˛ udostepniamy ˛ jej takie same przywileje, jakie posiadaja˛ funkcje skladowe klasy. Potrzeba istnienia funkcji zaprzyjaźnionych pojawia sie˛ cz˛esto w wyniku przeciażania ˛ operatora binarnego (np. operator * w kalsie Time): A = B * 3.4; –> A = B.operator*(3.4); A = 3.4 * B; –> Brak odpowiedniej metody ! Rozwiazaniem ˛ jest definicja funkcja postaci: Time operator*(double n, const Time & c) const; Ale taki prtotyp nie może być funkcja składowa˛ klasy !!! Rozwiaznie: ˛ zaprzyjaźnienie. Program wykonawczy # i f n d e f MYTIME3_H_ # d e f i n e MYTIME3_H_ # i n c l u d e < iostream > u s i n g s t d : : ostream ; c l a s s Time { private : i n t hours ; i n t minutes ; public : Time ( ) ; Time ( i n t h , i n t m = 0 ) ; v o i d AddMin ( i n t m) ; v o i d AddHr ( i n t h ) ; v o i d Reset ( i n t h = 0 , i n t m = 0 ) ; Time o p e r a t o r +( c o n s t Time & t ) c o n s t ; Time o p e r a t o r −( c o n s t Time & t ) c o n s t ; Time o p e r a t o r ∗ ( double n ) c o n s t ; f r i e n d Time o p e r a t o r ∗ ( double m, c o n s t Time & t ) { r e t u r n t ∗ m; } / / d e f i n i c j a miejscowa ( i n l i n e ) f r i e n d ostream & o p e r a t o r < <( ostream & os , c o n s t Time & t ) ; }; #endif mytime3.cpp - operator * #include <iostream> #include "mytime3.h" ... Time Time::operator*(double mult) const { Time result; long totalminutes = hours * mult * 60 + minutes * mult; result.hours = totalminutes / 60; result.minutes = totalminutes % 60; return result; } ... mytime3.cpp - operator « #include <iostream> #include "mytime3.h" ... ostream & operator<<(ostream & os, const Time & t) { os << t.hours << " godzin, " << t.minutes << " minut"; return os; } ... Program wykonawczy # i n c l u d e < iostream > # i n c l u d e " mytime3 . h " u s i n g namespace s t d ; i n t main ( ) { Time a i d a ( 3 , 3 5 ) , t o s c a ( 2 , 4 8 ) , temp ; c o u t << " Aida i Tosca : \ n " ; c o u t << a i d a < <"; " << t o s c a << e n d l ; temp = a i d a + t o s c a ; / / operator +() c o u t << " Aida + Tosca : " << temp << e n d l ; temp = a i d a ∗ 1 . 1 7 ; / / metoda o p e r a t o r ∗ ( ) c o u t << " Aida ∗ 1 . 1 7 : " << temp << e n d l ; c o u t << "10 ∗ Tosca : " << 10 ∗ t o s c a << e n d l ; return 0; } Wykonanie Aida i Tosca: 3 godzin, 35 minut; 2 godzin, 48 minut Aida + Tosca: 6 godzin, 23 minut Aida * 1.17: 4 godzin, 11 minut 10 * Tosca: 28 godzin, 0 minut Przykład realizowany na wykładzie Klasa ułamek. Wstepne ˛ pliki załaczone. ˛ jako źródła.