Obiekty stałe i metody z modyfikatorem const
Bogdan Kreczmer
bogdan.kreczmer@pwr.wroc.pl
Zakład Podstaw Cybernetyki i Robotyki
Instytut Informatyki, Automatyki i Robotyki
Politechnika Wrocławska
Kurs: Programowanie obiektowe
Copyright c
°2010 Bogdan Kreczmer
Niniejszy dokument zawiera materiały do wykładu dotyczącego programowania obiektowego. Jest on
udostępniony pod warunkiem wykorzystania wyłącznie do własnych prywatnych potrzeb i może on być kopiowany
wyłącznie w całości, razem z niniejszą stroną tytułową.
Programowanie obiektowe
Niniejsza prezentacja została wykonana przy użyciu sys-
temu składu L
A
TEX oraz stylu beamer, którego autorem
jest Till Tantau.
Strona domowa projektu Beamer:
http://latex-beamer.sourceforge.net
Programowanie obiektowe
Plan prezentacji
1
Programowanie obiektowe
Wykorzystanie zmiennych globalnych jako stałych
float RokGwiazdowy Dni = 365.256;
int
Doba Godziny = 24;
float ObliczIloscGodzin LataGwiazdowe( float LataGwiazdowe )
{
return RokGwiazdowy Dni∗Doba Godziny∗LataGwiazdowe;
}
int main( )
{
cout
<<
ObliczIloscGodzin LataGwiazdowe(0.00273781)
<<
endl;
}
Programowanie obiektowe
Wykorzystanie zmiennych globalnych jako stałych
float RokGwiazdowy Dni = 365.256;
int
Doba Godziny = 24;
float ObliczIloscGodzin LataGwiazdowe( float LataGwiazdowe )
{
return RokGwiazdowy Dni∗Doba Godziny∗LataGwiazdowe;
}
int main( )
{
cout
<<
ObliczIloscGodzin LataGwiazdowe(0.00273781)
<<
endl;
}
Programowanie obiektowe
Wykorzystanie zmiennych globalnych jako stałych
float RokGwiazdowy Dni = 365.256;
int
Doba Godziny = 24;
float ObliczIloscGodzin LataGwiazdowe( float LataGwiazdowe )
{
return
RokGwiazdowy Dni
∗
Doba Godziny
∗LataGwiazdowe;
}
int main( )
{
cout
<<
ObliczIloscGodzin LataGwiazdowe(0.00273781)
<<
endl;
}
Implementują procedurę przeliczania ziemskich lat gwiazdowych
na godziny dobrze jest użyć parametrów zewnętrznych, które nie
będą zmieniać się w trakcie działania programu.
Programowanie obiektowe
Wykorzystanie zmiennych globalnych jako stałych
float RokGwiazdowy Dni = 365.256;
int
Doba Godziny = 24;
float ObliczIloscGodzin LataGwiazdowe( float LataGwiazdowe )
{
return RokGwiazdowy Dni∗Doba Godziny∗LataGwiazdowe;
}
int main( )
{
cout
<<
ObliczIloscGodzin LataGwiazdowe(0.00273781)
<<
endl;
}
Pozwala to łatwo dostosować program, gdy będziemy chcieli go
użyć w odniesieniu do lat marsjańskich.
Programowanie obiektowe
Wykorzystanie zmiennych globalnych jako stałych
float RokGwiazdowy Dni = 686,9601
;
int
Doba Godziny = 24;
float ObliczIloscGodzin LataGwiazdowe( float LataGwiazdowe )
{
return RokGwiazdowy Dni∗Doba Godziny∗LataGwiazdowe;
}
int main( )
{
cout
<<
ObliczIloscGodzin LataGwiazdowe(0.00273781)
<<
endl;
}
Pozwala to łatwo dostosować program, gdy będziemy chcieli go
użyć w odniesieniu do lat marsjańskich.
Programowanie obiektowe
Wykorzystanie zmiennych globalnych jako stałych
float RokGwiazdowy Dni = 365.256;
int
Doba Godziny = 24;
float ObliczIloscGodzin LataGwiazdowe( float LataGwiazdowe )
{
return RokGwiazdowy Dni∗Doba Godziny∗LataGwiazdowe;
}
int main( )
{
cout
<<
ObliczIloscGodzin LataGwiazdowe(0.00273781)
<<
endl;
}
Wracajmy na Ziemię. Tu jest po prostu fajniej :)
Programowanie obiektowe
Wykorzystanie zmiennych globalnych jako stałych
float RokGwiazdowy Dni = 365.256;
int
Doba Godziny = 24;
float ObliczIloscGodzin LataGwiazdowe( float LataGwiazdowe )
{
return RokGwiazdowy Dni
∗=
Doba Godziny∗LataGwiazdowe;
}
int main( )
{
cout
<<
ObliczIloscGodzin LataGwiazdowe(0.00273781)
<<
endl;
}
Programowanie obiektowe
Wykorzystanie zmiennych globalnych jako stałych
float RokGwiazdowy Dni = 365.256;
int
Doba Godziny = 24;
float ObliczIloscGodzin LataGwiazdowe( float LataGwiazdowe )
{
return RokGwiazdowy Dni
∗=
Doba Godziny∗LataGwiazdowe;
}
int main( )
{
cout
<<
ObliczIloscGodzin LataGwiazdowe(0.00273781)
<<
endl;
}
Posługiwanie się zmiennymi, w przypadku gdy ich wartości nie
powinny ulegać zmianie, może łatwo prowadzić do przypadkowych
błędów.
Programowanie obiektowe
Definiowanie stałych
const float RokGwiazdowy Dni = 365.256;
const int
Doba Godziny = 24;
float ObliczIloscGodzin LataGwiazdowe( float LataGwiazdowe )
{
return RokGwiazdowy Dni
∗=
Doba Godziny∗LataGwiazdowe;
}
int main( )
{
cout
<<
ObliczIloscGodzin LataGwiazdowe(0.00273781)
<<
endl;
}
Wykorzystanie modyfikatora const do zdefiniowania stałych zapo-
biega tego typu sytuacjom.
Programowanie obiektowe
Definiowanie stałych
const float RokGwiazdowy Dni = 365.256;
const int
Doba Godziny = 24;
float ObliczIloscGodzin LataGwiazdowe( float LataGwiazdowe )
{
return
RokGwiazdowy Dni
∗=Doba Godziny∗LataGwiazdowe;
}
int main( )
{
cout
<<
ObliczIloscGodzin LataGwiazdowe(0.00273781)
<<
endl;
}
Próba modyfikacji wartości stałej zostanie wykryta na etapie kom-
pilacji. Pozwala to łatwo i szybko skorygować błąd, który w innym
przypadku byłby bardzo trudny do wykrycia.
Programowanie obiektowe
Definiowanie stałych
const float RokGwiazdowy Dni = 365.256;
const int
Doba Godziny = 24;
float ObliczIloscGodzin LataGwiazdowe( float LataGwiazdowe )
{
return
RokGwiazdowy Dni
∗
Doba Godziny
∗LataGwiazdowe;
}
int main( )
{
cout
<<
ObliczIloscGodzin LataGwiazdowe(0.00273781)
<<
endl;
}
Programowanie obiektowe
Definiowanie stałych
const float RokGwiazdowy Dni = 365.256;
const int
Doba Godziny = 24;
. . .
int main( )
{
. . .
bool ZajeteTerminy[Doba Godziny];
. . .
}
Programowanie obiektowe
Definiowanie stałych
const float RokGwiazdowy Dni = 365.256;
const int
Doba Godziny = 24;
. . .
int main( )
{
. . .
bool ZajeteTerminy[
Doba Godziny
];
. . .
}
Programowanie obiektowe
Definiowanie stałych
const float RokGwiazdowy Dni = 365.256;
int
Doba Godziny = 24;
. . .
int main( )
{
. . .
bool ZajeteTerminy[
Doba Godziny
];
. . .
}
Programowanie obiektowe
Definiowanie stałych
const float RokGwiazdowy Dni = 365.256;
int
Doba Godziny = 24;
. . .
int main( )
{
. . .
bool ZajeteTerminy[
Doba Godziny
];
hhh
hhh
hhh
hhh
hhh
hhh
hhh
hhh
hhh
hhh
hhh
hhh
((
((
((
((
(
((
((
((
((
(
((
((
((
((
(
((
((
((
((
(
. . .
}
Użycie zmiennych do definiowania rozmiaru tablicy jest niedopuszczalne w
ANSI/ISO C++. Jest natomiast dopuszczalne w niektórych rozszerzeniach
(np. gcc) i normie C99.
Programowanie obiektowe
Stałe versus symbole definiowane dla preprocesora
const float RokGwiazdowy Dni = 365.256;
const int
Doba Godziny = 24;
#define ROZMIAR NAPISU
100
. . .
int main( )
{
. . .
char TerminarzSpotkan[Doba Godziny][ROZMIAR NAPISU];
. . .
}
Programowanie obiektowe
Stałe versus symbole definiowane dla preprocesora
const float RokGwiazdowy Dni = 365.256;
const int
Doba Godziny = 24;
#define ROZMIAR NAPISU
100
. . .
int main( )
{
. . .
char TerminarzSpotkan[Doba Godziny][
ROZMIAR NAPISU
];
. . .
}
Programowanie obiektowe
Stałe versus symbole definiowane dla preprocesora
const float RokGwiazdowy Dni = 365.256;
int
Doba Godziny = 24;
#define ROZMIAR NAPISU
100
. . .
int main( )
{
. . .
char TerminarzSpotkan[Doba Godziny][
ROZMIAR NAPISU
];
. . .
}
Kiedy używać stałych, a kiedy symboli definiowanych dla preprocesora?
Programowanie obiektowe
Stałe versus symbole definiowane dla preprocesora
const float RokGwiazdowy Dni = 365.256;
int
Doba Godziny = 24;
#define ROZMIAR NAPISU
100
. . .
int main( )
{
. . .
char TerminarzSpotkan[Doba Godziny][
ROZMIAR NAPISU
];
. . .
}
Stałe zapewniają lepszą kontrolę typu w trakcie kompilacji. Należy je wów-
czas stosować tam, gdzie kod jest czuły na typ zmiennej, np. stosowanie
dużej ilości przeciążeń.
Programowanie obiektowe
Inicjalizacja stałych
const float RokGwiazdowy Dni;
const int
Doba Godziny;
#define ROZMIAR NAPISU
100
. . .
int main( )
{
. . .
char TerminarzSpotkan[Doba Godziny][ROZMIAR NAPISU];
. . .
}
Czy można zapomnieć zainicjalizować wartości stałych?
Programowanie obiektowe
Inicjalizacja stałych
const float RokGwiazdowy Dni;
const int
Doba Godziny;
#define ROZMIAR NAPISU
100
. . .
int main( )
{
. . .
char TerminarzSpotkan[Doba Godziny][
ROZMIAR NAPISU
];
. . .
}
Oczywiście tak :).
Programowanie obiektowe
Inicjalizacja stałych
const float RokGwiazdowy Dni;
const int
Doba Godziny;
#define ROZMIAR NAPISU
100
. . .
int main( )
{
. . .
char TerminarzSpotkan[Doba Godziny][
ROZMIAR NAPISU
];
. . .
}
Oczywiście tak :).
Jednak wykryte to zostanie przez kompilator.
Programowanie obiektowe
Inicjalizacja stałych
const float RokGwiazdowy Dni;
const int
Doba Godziny;
#define ROZMIAR NAPISU
100
. . .
int main( )
{
. . .
char TerminarzSpotkan[Doba Godziny][
ROZMIAR NAPISU
];
. . .
}
jkowalsk@noxon: prog> g++ stale.cpp
stale.cpp:4: error: uninitialized const ’RokGwiazdowy Dni’
stale.cpp:5: error: uninitialized const ’Doba Godziny’
Programowanie obiektowe
Czy zawsze stałe są stałe?
const float RokGwiazdowy Dni = 1.921;
const int
Doba Godziny = 2808;
. . .
int main( )
{
. . .
Doba Godziny = 24
;
. . .
}
To oczywiście jest błędem, gdyż wartość zmiennej Doba Godziny można
tylko odczytać.
Programowanie obiektowe
Czy zawsze stałe są stałe?
const float RokGwiazdowy Dni = 1.921;
const int
Doba Godziny = 2808;
. . .
int main( )
{
. . .
(int&) Doba Godziny = 24
;
. . .
}
Wartość stałej można jednak zmienić dokonując rzutowania. W języku C
wygląda to jak wyżej.
Programowanie obiektowe
Czy zawsze stałe są stałe?
const float RokGwiazdowy Dni = 1.921;
const int
Doba Godziny = 2808;
. . .
int main( )
{
. . .
const cast<int&>(Doba Godziny) = 24
;
. . .
}
W języku C++ zostały wprowadzone specjalne operatory rzutowania. Dają
one lepszą kontrolę typów.
Programowanie obiektowe
Czy stałe zmieniać warto i czemu nie warto
Zmiana wartości stałych w kodzie programu nie jest
dobrym rozwiązaniem. Takie działanie powoduje
zazwyczaj zmniejszenie czytelności kodu i zwiększa
ryzyko powstania błędów.
Zmiany wartości stałych są zwykle przejawem złego
stylu programowania.
Programowanie obiektowe
Czy stałe zmieniać warto i czemu nie warto
Zmiana wartości stałych w kodzie programu nie jest
dobrym rozwiązaniem. Takie działanie powoduje
zazwyczaj zmniejszenie czytelności kodu i zwiększa
ryzyko powstania błędów.
Zmiany wartości stałych są zwykle przejawem złego
stylu programowania.
Programowanie obiektowe
Plan prezentacji
1
Programowanie obiektowe
Obiekty stałe
struct LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
float
re;
float
im;
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
const LZespolona
Z = { 14, 12 };
float
Liczba = 3;
Liczba = Z. re;
}
Programowanie obiektowe
Obiekty stałe
struct LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
float
re;
float
im;
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
const LZespolona
Z = { 14, 12 }
;
float
Liczba = 3;
Liczba = Z. re;
}
Inicjalizacja obiektu w stylu języka C.
Programowanie obiektowe
Obiekty stałe
struct LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
float
re;
float
im;
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
LZespolona
Z modyf;
const LZespolona
Z = Z modyf
;
float
Liczba = 3;
Liczba = Z. re;
}
Obiekt stały można zainicjalizować wartościami innego obiektu.
Tym obiektem może być zarówno obiekt modyfikowalny . . .
Programowanie obiektowe
Obiekty stałe
struct LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
float
re;
float
im;
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
const LZespolona
Z staly = { 14, 12 };
const LZespolona
Z = Z staly
;
float
Liczba = 3;
Liczba = Z. re;
}
Obiekt stały można zainicjalizować wartościami innego obiektu.
Tym obiektem może być zarówno obiekt modyfikowalny
jak też
inny obiekt stały.
Programowanie obiektowe
Obiekty stałe
struct LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
float
re;
float
im;
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
const LZespolona
Z = { 14, 12 };
float
Liczba = 3;
Liczba = Z. re
;
}
Wróćmy do poprzedniej postaci.
Programowanie obiektowe
Obiekty stałe
struct LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
float
re;
float
im;
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
const LZespolona
Z = { 14, 12 };
float
Liczba = 3;
Z. re = Liczba
;
}
Czy można zmodyfikować wartość jakiegoś pola obiektu stałe-
go?
Programowanie obiektowe
Obiekty stałe
struct LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
float
re;
float
im;
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
const LZespolona
Z = { 14, 12 };
float
Liczba = 3;
Z. re = Liczba
;
P
P
P
³
³
³
}
Wartość żadnego z pól obiektu stałego nie może ulec zmianie.
Programowanie obiektowe
Obiekty stałe
struct LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
float
re;
float
im;
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
const LZespolona
Z = { 14, 12 };
float
Liczba = 3;
Liczba = Z. re;
}
Programowanie obiektowe
Obiekty stałe
struct LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
float
re;
float
im;
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
const LZespolona
Z
;
float
Liczba = 3;
Liczba = Z. re;
}
Czy można zapomnieć zainicjalizować obiekt?
Programowanie obiektowe
Obiekty stałe
struct LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
float
re;
float
im;
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
const LZespolona
Z
;
float
Liczba = 3;
Liczba = Z. re;
}
Czy można zapomnieć zainicjalizować obiekt?
Brak inicjalizacji
obiektu stałego wykrywany jest przez kompilator.
Programowanie obiektowe
Obiekty stałe
struct LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
float
re;
float
im;
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
const LZespolona
Z
;
float
Liczba = 3;
Liczba = Z. re;
}
jkowalsk@noxon: prog> g++ obiekt staly.cpp
obiekt staly.cpp: In function ’int main( )’:
obiekt staly.cpp:9: error: uninitialized const ’Z’
Programowanie obiektowe
Obiekty stałe
struct LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
float
re;
float
im;
LZespolona( ) { re = im = 0; }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
const LZespolona
Z;
float
Liczba = 3;
Liczba = Z. re;
}
Inicjalizację obiektu można zrealizować również poprzez utwo-
rzenie i niejawne wywołanie konstruktora.
Programowanie obiektowe
Obiekty stałe
struct LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
float
re;
float
im;
LZespolona( ) { re = im = 0; }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
const LZespolona
Z;
float
Liczba = 3;
Liczba = Z. re;
}
Inicjalizację obiektu można zrealizować również poprzez utwo-
rzenie i niejawne wywołanie konstruktora.
Dla języka C++ jest
to najbardziej naturalny sposób inicjalizacji obiektów.
Programowanie obiektowe
Obiekty stałe
struct LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
float
re;
float
im;
LZespolona( ) { }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
const LZespolona
Z;
float
Liczba = 3;
Liczba = Z. re;
}
A czy teraz obiekt jest zainicjalizowany?
Programowanie obiektowe
Obiekty stałe
struct LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
float
re;
float
im;
LZespolona( ) { }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
const LZespolona
Z;
float
Liczba = 3;
Liczba = Z. re;
}
Z formalnego punktu widzenia tak, gdyż zrealizowany został
proces inicjalizacji poprzez wywołanie konstruktora.
Programowanie obiektowe
Obiekty stałe
struct LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
float
re;
float
im;
LZespolona( ) { }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
const LZespolona
Z;
float
Liczba = 3;
Liczba = Z. re;
}
Nie oznacza to jednak, że w jego trakcie muszą zostać zaini-
cjalizowane wartości jakiegokolwiek pola danej klasy.
Programowanie obiektowe
Obiekty stałe
struct LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
float
re;
float
im;
LZespolona( ) { re = im = 0; }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
const LZespolona
Z;
float
Liczba = 3;
Liczba = Z. re;
}
Powróćmy do poprzedniej formy inicjalizacji.
Programowanie obiektowe
Obiekty stałe
struct LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
float
re;
float
im;
LZespolona( ) { re = im = 0; }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
const LZespolona
Z;
float
Liczba = 3;
Z. re = Liczba
;
}
Tak jak w przypadku zwykłych stałych można wymusić zmianę
wartości danego pola poprzez odpowiednie rzutowanie. Tym
razem można to zrealizować na dwa sposoby.
Programowanie obiektowe
Obiekty stałe
struct LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
float
re;
float
im;
LZespolona( ) { re = im = 0; }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
const LZespolona
Z;
float
Liczba = 3;
const cast<float&>(Z. re) = Liczba
;
}
1. Traktujemy pole jako zwykłą stałą i dokonujemy jego zrzu-
towania.
Programowanie obiektowe
Obiekty stałe
struct LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
float
re;
float
im;
LZespolona( ) { re = im = 0; }
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
const LZespolona
Z;
float
Liczba = 3;
const cast<LZespolona&>(Z). re = Liczba
;
}
2. Najpierw dokonujemy zrzutowania obiektu pozbawiając go
modyfikatora const.
Programowanie obiektowe
Obiekty stałe
Wszystkie uwagi dotyczące wymuszania zmian wartości
zwykłych stałych dotyczą również obiektów stałych.
A więc:
Zmiana wartości obiektów stałych w kodzie programu
nie jest dobrym rozwiązaniem. Takie działanie
powoduje zazwyczaj zmniejszenie czytelności kodu i
zwiększa ryzyko powstania błędów.
Zmiany wartości obiektów stałych są zwykle
przejawem złego stylu programowania.
Programowanie obiektowe
Obiekty stałe
Wszystkie uwagi dotyczące wymuszania zmian wartości
zwykłych stałych dotyczą również obiektów stałych.
A więc:
Zmiana wartości obiektów stałych w kodzie programu
nie jest dobrym rozwiązaniem. Takie działanie
powoduje zazwyczaj zmniejszenie czytelności kodu i
zwiększa ryzyko powstania błędów.
Zmiany wartości obiektów stałych są zwykle
przejawem złego stylu programowania.
Programowanie obiektowe
Zmienne jako stałe
Obiekty stałe
Plan prezentacji
1
Zmienne jako stałe
Obiekty stałe
Programowanie obiektowe
Zmienne jako stałe
Obiekty stałe
Posługiwanie się metodami stałymi
struct LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
LZespolona( ) { re = im = 0; }
float Re( ) { return
re; }
float Im( ) { return
im; }
float Zmien(float re, float im) { re = re;
im = im; }
private
float
re, im;
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
const LZespolona
Z;
float
Liczba = 3;
}
Programowanie obiektowe
Zmienne jako stałe
Obiekty stałe
Posługiwanie się metodami stałymi
struct LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
LZespolona( ) { re = im = 0; }
float Re( ) { return
re; }
float Im( ) { return
im; }
float Zmien(float re, float im) { re = re;
im = im; }
private
float
re
,
im
;
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
const LZespolona
Z;
float
Liczba = 3;
}
Programowanie obiektowe
Zmienne jako stałe
Obiekty stałe
Posługiwanie się metodami stałymi
struct LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
LZespolona( ) { re = im = 0; }
float Re( ) { return
re; }
float Im( ) { return
im; }
float Zmien(float re, float im) { re = re;
im = im; }
private
float
re
,
im
;
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
const LZespolona
Z;
float
Liczba = 3;
}
Programowanie obiektowe
Zmienne jako stałe
Obiekty stałe
Posługiwanie się metodami stałymi
struct LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
LZespolona( ) { re = im = 0; }
float Re( ) { return
re; }
float Im( ) { return
im; }
float Zmien(float re, float im) { re = re;
im = im; }
private
float
re, im;
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
const LZespolona
Z;
float
Liczba = 3;
Liczba = Z. re
;
}
Programowanie obiektowe
Zmienne jako stałe
Obiekty stałe
Posługiwanie się metodami stałymi
struct LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
LZespolona( ) { re = im = 0; }
float Re( ) { return
re; }
float Im( ) { return
im; }
float Zmien(float re, float im) { re = re;
im = im; }
private
float
re, im;
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
const LZespolona
Z;
float
Liczba = 3;
Liczba = Z.Re( );
}
Czy tak będzie już dobrze?
Programowanie obiektowe
Zmienne jako stałe
Obiekty stałe
Posługiwanie się metodami stałymi
struct LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
LZespolona( ) { re = im = 0; }
float Re( ) { return
re; }
float Im( ) { return
im; }
float Zmien(float re, float im) { re = re;
im = im; }
private
float
re, im;
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
LZespolona
Z;
float
Liczba = 3;
Liczba = Z.Re( );
}
Tak byłoby dobrze gdyby to był obiekt modyfikowalny.
Programowanie obiektowe
Zmienne jako stałe
Obiekty stałe
Posługiwanie się metodami stałymi
struct LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
LZespolona( ) { re = im = 0; }
float Re( ) { return
re; }
float Im( ) { return
im; }
float Zmien(float re, float im) { re = re;
im = im; }
private
float
re, im;
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
const LZespolona
Z;
float
Liczba = 3;
Liczba =
Z.Re( )
;
P
P
P
³
³
³
}
W przypadku obiektu stałego wywołanie tego typu metody nie jest
dopuszczalne.
Programowanie obiektowe
Zmienne jako stałe
Obiekty stałe
Posługiwanie się metodami stałymi
struct LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
LZespolona( ) { re = im = 0; }
float Re( ) const { return
re; }
float Im( ) const { return
im; }
float Zmien(float re, float im) { re = re;
im = im; }
private
float
re, im;
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
const LZespolona
Z;
float
Liczba = 3;
Liczba = Z.Re( );
}
Dla obiektów stałych mogą być tylko wywoływane metody stałe, tzn.
takie, które nie modyfikują obiektu.
Programowanie obiektowe
Zmienne jako stałe
Obiekty stałe
Posługiwanie się metodami stałymi
struct LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
LZespolona( ) { re = im = 0; }
float Re( ) const { return
re; }
float Im( ) const { return
im; }
float Zmien(float re, float im) { re = re;
im = im; }
private
float
re, im;
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
LZespolona
Z;
float
Liczba = 3;
Liczba = Z.Re( );
}
Metody stałe mogą być również wywoływane dla obiektów modyfi-
kowalnych.
Programowanie obiektowe
Zmienne jako stałe
Obiekty stałe
Obiekty stałe i metody modyfikujące obiekt
struct LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
LZespolona( ) { re = im = 0; }
float Re( ) const { return
re; }
float Im( ) const { return
im; }
float Zmien(float re, float im) { re = re;
im = im; }
private
float
re, im;
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
LZespolona
Z;
float
Liczba = 3;
Z.Zmien( Liczba, 2.5 );
}
Dotyczy to również metod mogących modyfikować obiekt.
Programowanie obiektowe
Zmienne jako stałe
Obiekty stałe
Obiekty stałe i metody modyfikujące obiekt
struct LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
LZespolona( ) { re = im = 0; }
float Re( ) const { return
re; }
float Im( ) const { return
im; }
float Zmien(float re, float im) { re = re;
im = im; }
private
float
re, im;
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
const LZespolona
Z;
float
Liczba = 3;
Z.Zmien( Liczba, 2.5 )
;
}
Tak nie jest w przypadku obiektów stałych.
Programowanie obiektowe
Zmienne jako stałe
Obiekty stałe
Obiekty stałe i metody modyfikujące obiekt
struct LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
LZespolona( ) { re = im = 0; }
float Re( ) const { return
re; }
float Im( ) const { return
im; }
float Zmien(float re, float im) { re = re;
im = im; }
private
float
re, im;
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
const LZespolona
Z;
float
Liczba = 3;
const cast<LZespolona&>(Z).Zmien( Liczba, 2.5 );
}
Można to jednak wymusić poprzez odpowiednie rzutowanie obiektu,
dla którego wywoływana jest dana metoda.
Programowanie obiektowe
Zmienne jako stałe
Obiekty stałe
Metody stałe modyfikujące obiekt (???)
8−O
struct LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
LZespolona( ) { re = im = 0; }
float Re( ) const { return
re; }
float Im( ) const { return
im; }
float Zmien(float re, float im) const { re = re;
im = im; }
private
float
re, im;
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
const LZespolona
Z;
float
Liczba = 3;
Z.Zmien( Liczba, 2.5 );
}
A czy można to rozwiązać inaczej, tzn. poprzez zmianę statusu me-
tody Zmien i zdefiniowanie jej jako metody stałej?
Programowanie obiektowe
Zmienne jako stałe
Obiekty stałe
Metody stałe nie mogą modyfikować obiektu
struct LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
LZespolona( ) { re = im = 0; }
float Re( ) const { return
re; }
float Im( ) const { return
im; }
float Zmien(float re, float im) const { re = re;
im = im; }
P
P
P
³
³
³
P
P
P
³
³
³
private
float
re, im;
}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
int main( )
{
const LZespolona
Z;
float
Liczba = 3;
Z.Zmien( Liczba, 2.5 );
}
W metodzie stałej wszystkie pola obiektu są traktowane jako tylko
do odczytu. Operacje podstawienia byłyby niemożliwe.
Programowanie obiektowe
I to już koniec.
Programowanie obiektowe