Tomasz Marks - Wydział MiNI PW
-1-
Programowanie Obiektowe
(j
ę
zyk C++)
Wykład 2.
Tomasz Marks - Wydział MiNI PW
-2-
Przypomnienie ...
referencje
Tomasz Marks - Wydział MiNI PW
-3-
Referencje (1)
• Referencja (odno
ś
nik) jest zmienn
ą
identyfikuj
ą
c
ą
inn
ą
zmienn
ą
.
• Wykonanie operacji na referencji ma taki sam
skutek, jak wykonanie tej
ż
e operacji na zmiennej
identyfikowanej przez t
ę
referencj
ę
.
Np.
int Num = 50;
int& Ref = Num;
Ref++;
cout << Num << Ref;
// 51 51
Tomasz Marks - Wydział MiNI PW
-4-
int Num = 50;
zdefiniowano zmienn
ą
Num
(typu int) nadaj
ą
c jej warto
ść
pocz
ą
tkow
ą
50.
int& Ref = Num;
zdefiniowano zmienn
ą
Ref
(typu referencja do int) i skojarzono j
ą
ze
zmienn
ą
Num.
Ref++;
inkrementacja zmiennej Ref,
to
ż
sama z inkrementacj
ą
zmiennej Num.
cout << Ref << Num;
zmienne Ref i Num,
to faktycznie ta sama zmienna.
Tomasz Marks - Wydział MiNI PW
-5-
UWAGA:
Zabrania si
ę
konstruowania deklaracji:
referencja-do-referencji
// int && ref
wskazanie-referencji
// int &* ptr
tablica-referencji
// int & arr[5]
Tomasz Marks - Wydział MiNI PW
-6-
Jeszcze jeden przykład
{
int n1, n2;
int &ref = n1;
n1 = 10; n2 = 20;
cout << n1 << n2 << ref;
// 10 20 10
ref = n2; n2 = 30;
cout << n1 << n2 << ref;
// 20 30 20
ref = ref + 3;
cout << n1 << n2 << ref;
// 23 30 23
}
Tomasz Marks - Wydział MiNI PW
-7-
Referencje (2)
• Referencja mo
ż
e by
ć
inicjowana stał
ą
. Wymaga si
ę
wtedy, aby definiowana zmienna była okre
ś
lona jako
referencja do zmiennej ustalonej.
• W takim przypadku tworzona jest zmienna
tymczasowa inicjowana warto
ś
ci
ą
stałej i wszystkie
odwołania do zmiennej referencyjnej kierowane s
ą
do tej zmiennej tymczasowej.
Np.
const int &Ref = 50;
cout << Ref;
// 50
Ref = 33;
//
BŁ
Ą
D:
próba modyfikacji zmiennej ustalonej
Tomasz Marks - Wydział MiNI PW
-8-
Referencje (3)
• Parametr funkcji mo
ż
e by
ć
okre
ś
lony jako referencja.
W takim przypadku odpowiedni argument wywołania
funkcji musi by
ć
wyra
ż
eniem okre
ś
laj
ą
cym zmienn
ą
odpowiedniego typu – nie mo
ż
e by
ć
n.p. sum
ą
zmiennych.
N.p.
void fun( double& x );
double a, b;
.....................
fun( a );
// O.K.
fun( a + b );
//
Ź
le !!!
Tomasz Marks - Wydział MiNI PW
-9-
Referencje (4)
• Rezultat funkcji mo
ż
e by
ć
referencj
ą
– wtedy
identyfikuje zmienn
ą
okre
ś
lon
ą
w instrukcji powrotu
(return).
• Wywołanie funkcji zwracaj
ą
cej referencj
ę
mo
ż
e
wyst
ą
pi
ć
wsz
ę
dzie tam, gdzie mo
ż
e wyst
ą
pi
ć
nazwa
zmiennej, a wi
ę
c np. jako:
- lewy argument operacji przypisania (=),
- prawy argument op. wprowadzania (>>),
- argument operacji utworzenia wskazania (&)
Tomasz Marks - Wydział MiNI PW
-10-
parametry
definicji funkcji
argumenty
wywołania funkcji
Tomasz Marks - Wydział MiNI PW
-11-
Sekwencja wymiany warto
ś
ci 2 zmiennych
{
int a, b;
a = 2;
b = 5;
// teraz chcemy zamieni
ć
warto
ś
ci
// pomi
ę
dzy zmiennymi a i b
int tmp;
tmp = a; a = b; b = tmp;
cout << a << b;
// 5 2
...................................
Tomasz Marks - Wydział MiNI PW
-12-
UWAGA:
W j
ę
zyku C++, w obr
ę
bie bloku deklaracje
mog
ą
si
ę
przeplata
ć
z instrukcjami.
Ale ...
(1) deklaracja zmiennej musi poprzedza
ć
jej u
ż
ycie
( tak jak w j
ę
zyku C ),
(2) deklaracja nie mo
ż
e by
ć
"przeskakiwana".
Tomasz Marks - Wydział MiNI PW
-13-
Funkcja C/C++
(zła)
zamieniaj
ą
ca warto
ś
ci zmiennych
void exchg1 ( int i, int j )
{
int tmp;
tmp = i; i = j; j = tmp;
}
…………………..
int a = 2, b = 5;
exchg1 ( a, b );
cout << a << b;
// 2 5
Tomasz Marks - Wydział MiNI PW
-14-
Funkcja C/C++
(zła)
zamieniaj
ą
ca warto
ś
ci zmiennych
int a = 2, b = 5;
exchg1 ( a, b );
// jest równowa
ż
ne realizacji bloku:
{
int i = a, j = b;
int tmp;
tmp = i; i = j; j = tmp;
}
cout << a << b;
// 2 5
Tomasz Marks - Wydział MiNI PW
-15-
Funkcja C/C++
(dobra)
zamieniaj
ą
ca warto
ś
ci zmiennych
void exchg2 ( int *i, int *j )
{
int tmp;
tmp = *i; *i = *j; *j = tmp;
}
…………………..
int a = 2, b = 5;
exchg2 ( &a, &b );
cout << a << b;
// 5 2
Tomasz Marks - Wydział MiNI PW
-16-
Funkcja C/C++
(dobra)
zamieniaj
ą
ca warto
ś
ci zmiennych
int a = 2, b = 5;
exchg2 ( &a, &b );
// jest równowa
ż
ne realizacji bloku:
{
int *i = &a, *j = &b;
int tmp;
tmp = *i; *i = *j; *j = tmp;
}
cout << a << b;
// 5 2
Tomasz Marks - Wydział MiNI PW
-17-
Funkcja C++
(dobra)
zamieniaj
ą
ca warto
ś
ci zmiennych
void exchg3 ( int &i, int &j )
{
int tmp;
tmp = i; i = j; j = tmp;
}
…………………..
int a = 2, b = 5;
exchg3 ( a, b );
cout << a << b;
// 5 2
Tomasz Marks - Wydział MiNI PW
-18-
Funkcja C++
(dobra)
zamieniaj
ą
ca warto
ś
ci zmiennych
int a = 2, b = 5;
exchg3 ( a, b );
// jest równowa
ż
ne realizacji bloku:
{
int &i = a, &j = b;
int tmp;
tmp = i; i = j; j = tmp;
}
cout << a << b;
// 5 2
Tomasz Marks - Wydział MiNI PW
-19-
Do zapami
ę
tania…
• Parametr funkcji jest jej zmienn
ą
lokaln
ą
zainicjowan
ą
argumentem wywołania
funkcji.
• Je
ż
eli parametr jest referencyjny, to
operacje dokonywane na parametrze
dotycz
ą
skojarzonego z nim argumentu.
Tomasz Marks - Wydział MiNI PW
-20-
Przypomnienie ... c.d.
Tomasz Marks - Wydział MiNI PW
-21-
przeci
ąż
anie
nazw funkcji
Tomasz Marks - Wydział MiNI PW
-22-
Przeci
ąż
anie nazw funkcji (1)
• W j
ę
zyku C jest niedopuszczalne!
Nazwy funkcji musz
ą
by
ć
unikatowe.
int Sum ( int a, int b ) { return a+b; }
int Sum3 ( int a, int b, int c ) { return a+b+c; }
double SumD ( double a, double b ) { return a+b; }
……………………
int i, j, k, m, n;
double x, y, z;
n = Sum ( i, j );
m = Sum3 (i, j, k );
z = SumD ( x, y );
Tomasz Marks - Wydział MiNI PW
-23-
Przeci
ąż
anie nazw funkcji (2)
• W j
ę
zyku C++ jest dopuszczalne
i bardzo cz
ę
sto wykorzystywane.
int Sum ( int a, int b ) { return a+b; }
int Sum ( int a, int b, int c ) { return a+b+c; }
double Sum ( double a, double b ) { return a+b; }
……………………
int i, j, k, m, n;
n = Sum ( i, j );
m = Sum (i, j, k );
double x, y, z;
z = Sum ( x, y );
Tomasz Marks - Wydział MiNI PW
-24-
Przeci
ąż
anie nazw funkcji (3)
• Ale uwaga!
Je
ż
eli kompilator "widzi" 2 funkcje
int Sum ( int a, int b ) { return a+b; }
double Sum ( double a, double b ) { return a+b; }
……………………
int i, j, k, m, n;
n = Sum ( i, j );
// O.K.
double x, y, z;
// def. zmiennych po instrukcji !
z = Sum ( x, y );
// O.K.
z = Sum ( x, i );
// BŁ
Ą
D
z = Sum ( 123, 55.5 );
// BŁ
Ą
D
Tomasz Marks - Wydział MiNI PW
-25-
Przeci
ąż
anie nazw funkcji (4)
• Liczba i typy argumentów wywołania funkcji
musz
ą
si
ę
da
ć
dokładnie dopasowa
ć
do liczby i
typów parametrów której
ś
z zadeklarowanych
funkcji.
• Trzeba tu jeszcze wiedzie
ć
,
ż
e
referencja do
TYP
jest nieodró
ż
nialna od
TYP
. Dlatego n.p.
nie mo
ż
na definiowa
ć
przeci
ąż
enia
int Sum ( int a, int b ) { return a+b; }
int Sum ( int &a, int &b ) { return a+b; }
Tomasz Marks - Wydział MiNI PW
-26-
domy
ś
lne warto
ś
ci
argumentów
Tomasz Marks - Wydział MiNI PW
-27-
Domy
ś
lne warto
ś
ci argumentów (1)
W j
ę
zyku C++ zamiast u
ż
ywa
ć
przeci
ąż
enia Sum
dla 2 i 3 parametrów typu int, wystarczy zdefiniowa
ć
jedn
ą
funkcj
ę
int Sum ( int a, int b, int c ) { return a+b+c; }
a nast
ę
pnie posłu
ż
y
ć
si
ę
deklaracj
ą
int Sum ( int, int, int=0 );
……………………
int i, j, k, m, n;
m = Sum (i, j, k );
n = Sum ( i, j );
// równowa
ż
ne n = Sum ( i, j, 0 );
Tomasz Marks - Wydział MiNI PW
-28-
Domy
ś
lne warto
ś
ci argumentów (2)
W skrajnym przypadku mo
ż
na u
ż
y
ć
deklaracji
int Sum ( int=0, int=0, int=0 );
……………………
int i, j, k, m, n;
m = Sum ( i, j, k );
// tyle argumentów ile parametrów
m = Sum ( i, j );
// równowa
ż
ne n = Sum ( i, j, 0 );
m = Sum ( i );
// równowa
ż
ne n = Sum ( i, 0, 0 );
m = Sum ( );
// równowa
ż
ne n = Sum ( 0, 0, 0 );
Tomasz Marks - Wydział MiNI PW
-29-
DEFINIOWANIE
KLAS
Tomasz Marks - Wydział MiNI PW
-30-
Definiowanie klas (1)
Klas
ę
mo
ż
na definiowa
ć
u
ż
ywaj
ą
c słowa kluczowego
struct
struct
NazwaKlasy
{
……………………………………….
.. składowe domy
ś
lnie publiczne ..
……………………………………….
……………………………………….
};
Tomasz Marks - Wydział MiNI PW
-31-
Definiowanie klas (2)
Klas
ę
mo
ż
na definiowa
ć
u
ż
ywaj
ą
c słowa kluczowego
class
class NazwaKlasy
{
……………………………………….
.. składowe domy
ś
lnie prywatne ...
……………………………………….
……………………………………….
};
Tomasz Marks - Wydział MiNI PW
-32-
public
private
protected
Tomasz Marks - Wydział MiNI PW
-33-
Definiowanie klas (3)
Okre
ś
lenia publiczne, prywatne zwi
ą
zane s
ą
z poj
ę
ciem
dost
ę
pno
ś
ci nazw składowych.
Domy
ś
lnie, dla składowych klasy definiowanej z u
ż
yciem
słowa kluczowego struct przyjmuje si
ę
dost
ę
p publiczny
(ma to na celu zapewnienie zgodno
ś
ci z j
ę
zykiem C).
Domy
ś
lnie, dla składowych klasy definiowanej z u
ż
yciem
słowa kluczowego class przyjmuje si
ę
dost
ę
p prywatny.
Do jawnego okre
ś
lania dost
ę
pno
ś
ci składowych słu
żą
słowa kluczowe:
public
,
private
,
protected
(chronione).
S
ą
to tzw. specyfikatory dost
ę
pno
ś
ci.
Tomasz Marks - Wydział MiNI PW
-34-
Definicja klasy CMPLX
struct
CMPLX
{
double Re, Im;
…………………
};
jest równowa
ż
na definicji
class CMPLX
{
public:
double Re, Im;
…………………
};
Tomasz Marks - Wydział MiNI PW
-35-
Definiowanie klas (4)
Specyfikatory dost
ę
pno
ś
ci składowych klasy:
public – nazw składowych
publicznych
mog
ą
u
ż
ywa
ć
wszystkie funkcje "widz
ą
ce" definicj
ę
klasy,
private – nazw składowych
prywatnych
mog
ą
u
ż
ywa
ć
jedynie metody danej klasy i funkcje zaprzyja
ź
nione z t
ą
klas
ą
,
protected - nazw składowych
chronionych
mog
ą
u
ż
ywa
ć
jedynie metody danej klasy i funkcje zaprzyja
ź
nione z t
ą
klas
ą
, oraz metody i funkcje zaprzyja
ź
nione klas
pochodnych tej klasy.
Tomasz Marks - Wydział MiNI PW
-36-
Napiszmy definicj
ę
klasy CMPLX w nowej wersji
class CMPLX
{
double Re, Im;
//
Re, Im s
ą
teraz prywatne
public:
double Abs ( ) const;
void Read ( );
};
Tomasz Marks - Wydział MiNI PW
-37-
W konsekwencji definicja funkcji
CMPLX Add ( CMPLX a, CMPLX b )
{
a.Re += b.Re;
a.Im += b.Im;
return a;
}
przestała by
ć
poprawna, bo zawiera
zabronione
odwołania do prywatnych pól klasy CMPLX.
Tomasz Marks - Wydział MiNI PW
-38-
Mo
ż
emy ten problem rozwi
ą
za
ć
na kilka sposobów.
(1) uzupełni
ć
definicj
ę
klasy CMPLX o prymitywne metody dost
ę
pu do pól:
class CMPLX
{
……………………….
public:
double getRe ( ) const { return Re; }
double getIm ( ) const { return Im; }
void setRe ( double re ) { Re = re; }
void setIm ( double im ) { Im = im; }
};
i napisa
ć
tre
ść
definicji funkcji Add w postaci jak ni
ż
ej
CMPLX Add ( CMPLX a, CMPLX b )
{
a.setRe ( a.getRe( ) + b.getRe( ) );
a.setIm ( a.getIm( ) + b.getIm( ) );
return a;
}
Tomasz Marks - Wydział MiNI PW
-39-
(2) uzupełni
ć
definicj
ę
klasy CMPLX o 2 metody dost
ę
pu do pól
wykorzystuj
ą
ce referencje:
class CMPLX
{
……………………….
public:
double& refRe ( ) { return Re; }
double& refIm ( ) { return Im; }
};
i napisa
ć
tre
ść
definicji funkcji Add w postaci jak ni
ż
ej
CMPLX Add ( CMPLX a, CMPLX b )
{
a.refRe( ) += b.refRe( ) ;
a.refIm( ) += b.refIm( ) ;
return a;
}
_
Tomasz Marks - Wydział MiNI PW
-40-
friend
Tomasz Marks - Wydział MiNI PW
-41-
(3) "Zaprzyja
ź
ni
ć
" funkcj
ę
Add z klas
ą
CMPLX:
class CMPLX
{
……………………….
……………………….
friend CMPLX Add ( CMPLX, CMPLX );
// deklaracja zaprzyja
ź
nienia
};
i pozostawi
ć
tre
ść
definicji funkcji Add w oryginalnej postaci.
S
ą
jeszcze inne mo
ż
liwo
ś
ci, ale o nich w tej chwili nie b
ę
dziemy mówili.
UWAGA:
Poło
ż
enie deklaracji zaprzyja
ź
nienia wzgl
ę
dem specyfikatorów
dost
ę
pno
ś
ci (public, private, protected) w obr
ę
bie definicji klasy
nie ma
ż
adnego znaczenia.
_
Tomasz Marks - Wydział MiNI PW
-42-
Nasza definicja klasy CMPLX (nowa)
// cmplx.h
class CMPLX
{
double Re, Im;
public:
void Set (double=0, double=0 );
void Read ( );
void Write ( ) const;
double Abs ( ) const;
friend CMPLX operator+ ( CMPLX, CMPLX );
};
Tomasz Marks - Wydział MiNI PW
-43-
Główny plik aplikacji
(nowy)
// myprog.cpp
#include < iostream >
using namespace std;
#include ”cmplx.h”
int main ( )
{
CMPLX x, y, z;
x.Read ( );
// cin
1.5 2.2
y.Set ( 2.0, 3.0 );
z = x + y;
z.Write( );
// cout
[ 3.5, 5.2 ]
}
Tomasz Marks - Wydział MiNI PW
-44-
Koniec wykładu 2.