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.