Transcript Wykład IX

Slide 1

Programowanie obiektowe
III rok EiT

dr inż. Jerzy Kotowski
Wykład IX


Slide 2

Program wykładu

• Język C++
– Klasy, c.d.
• Składowa statyczna klasy
• Wskaźniki do składowych klasy
• Funkcje składowe z atrybutem const

• Przykład problemu
• Podstawy języka JAVA

•Klasówka


Slide 3

Literatura
• C++ for C programmers, Ira Pohl, The
Benjamin/Cummings Publishing Company,
Inc.
• Symfonia C++, Jerzy Grębosz, Oficyna
Kallimach, Kraków 1999
• Borland C++ 4, Nabajyoti Barkakati,
Oficyna Wydawnicza README, Warszawa
1995


Slide 4

Składowa statyczna klasy








Data members mogą być deklarowane z modyfikatorem static.
W kontekście ze słowem kluczowym static nie można używać auto,
register lub extern.
Składnik static jest zakładany raz na klasę.
Statyczna może być również funkcja składowa.
class String
{
……………
static Stan;
public:
static void switch_stan(void);
……………
};
Składowa statyczna nie może odnosić się do niestatycznych składowych
klasy (bo może ich po prostu nie być).
Słowo static może się pojawić tylko wewnątrz definicji klasy:
void String::switch_stan(void)//Definicja funkcji poza klasą
{…}


Slide 5

Składowa statyczna klasy – c.d.





.. \test0.sln

String static.cpp
Statyczną składową należy zdefiniować poza klasą. Wewnątrz klasy jest
tylko deklaracja:
int String::Stan = 0;
Składowa statyczna może być private. Inicjalizacja tej składowej
powyższą techniką jest wtedy możliwa tylko raz.
Definicja funkcji statycznej może być wewnątrz klasy (inline) lub poza
klasą:
void String::switch_stan(void)
{
cout << "\nStan = ";
cout << (Stan? "gadamy.": "siedzimy cicho.");
cout << "
Zmiana? (t/n) ";
int p = getche();
if(p == 't' || p == 'T')
Stan ^= 1;
// ciekawostka: przełączanie 0-1
cout << endl;
}


Slide 6

Interesujące elementy programu
• Priorytety operatorów:
void print(){if (Stan) {cout << s << "\nLenght: " << len
<< "\n";} else cout <<"\n??";}
• Definicja statycznej składowej prywatnej:
int String::Stan = 0;
• Operator trójargumentowy:
cout << (Stan? "gadamy.": "siedzimy cicho.");
• Przełączanie wartości zmiennej binarnej:
Stan ^= 1;
• Wywołanie poprzez nazwę klasy:
String::switch_stan();
• Wywołanie poprzez obiekt:
one.switch_stan();
• Wywołanie poprzez adres do obiektu:
p->switch_stan();
• A variable declared static in a function retains (zachowuje) its state
between calls to that function:
static char three[40]…


Slide 7

Klasa punkt

..\..\Visual Studio Projects\test0\test0.sln

• Idea: Chcemy dysponować informacją o liczbie obiektów
• Sposób: statyczna składowa klasy i statyczna funkcja
składowa
• punkt.cpp
• Przy okazji:
– Pojawi się konstruktor z domniemanymi argumentami
– Konstruktor i destruktor będą modyfikować składową statyczną
klasy
– „Gadający” konstruktor i destruktor pozwolą obserwować
niejawne działania programu
– Aby to móc obserwować w destruktorze pojawi się wywołanie
funkcji getch()

• Komfort: nie musimy pamiętać o wielu rzeczach, które są
bardzo ważne dla poprawnej pracy programu. Ma to
miejsce przy dynamicznej rezerwacji pamięci.


Slide 8

Wskaźniki do składowych klasy






class complex
{
public:
float Re, Im;
void print(void);
}x;
float *p = &x.Re;
float (*wsk)(int,long);

Klasyczny wskaźnik zawiera adres
bezwzględny obiektu.
Pokazujemy na coś bezpośrednio
palcem (J. Grębosz) i mówimy:
naciśnij na to coś.
wsk jest wskaźnikiem do funkcji o
argumentach typu int oraz long
zwracającej wartość typu float.
Wskaźnik do składowej klasy: To jest hamulec (pokazujemy
hamulec na rysunku technicznym). Naciśnij na hamulec.
Idea: wiemy gdzie jest hamulec w samochodzie. Jedziemy jakimś
samochodem (tzn. obiektem klasy samochód). Wiemy gdzie ten
konkretny obiekt (egzemplarz pojęcia) ma hamulec w oparciu o
znajomość schematu technicznego tego typu samochodu (tzn.
tego typu obiektowego).


Slide 9

Wskaźniki do składowych klasy c.d.











Definicja wskaźnika (K jest nazwą klasy):
type_name K::*wsk;
Inicjalizacja:
type_name K::*wsk = & K::składnik_klasy;
Przykład:
float complex::*pk = &complex::Re;
Użycie:
x.*pk = 1;
Analogia: obiekt znany przez adres. To jest antena (pokazujemy anteną
na rysunku technicznym). Odkręć anteną z samochodu przed domem.
Przykład użycia
complex *w_o = &x;
float complex::*pl = &complex::Im;
w_o->*pl = -1;
Uwaga! Nie jest to sposób na obejście reguł dostępu do składowych.
Nie można zdefiniować wskaźnika do składowej, która nie ma swojej
nazwy (na przykład do elementu tablicy, będącej składową klasy).
Nowe operatory C++: .* oraz ->* Priorytet 14.


Slide 10

Wskaźniki do funkcji składowych












Wskaźnik do funkcji składowej:
type_name (K::*wsk_f)(type1,...);
Przykład:
void (complex::*wsk_f)(void) = complex::print;
Użycie - poprzez nazwę obiektu:
(x.*wsk_f)();
Użycie - poprzez adres obiektu
(w_o->*wsk_f)();
Uwaga na nawiasy!!!
Co to jest? float complex::*t_w[2];
t_w jest dwuelementową tablicą adresów do składowych typu float w
klasie complex
Użycie: t_w[0]=&complex::Re;
Co to jest? void (complex::*wf[2])(void);
wf jest dwuelementową tablicą wskaźników do funkcji składowych typu
void-void w klasie complex
Użycie:
void (complex::*wf[2])(void) = {NULL, complex::print};
(x.*t_wsk_f[1])();


Slide 11

Wskaźniki do składowych statycznych
• Składnia definiowania i używania wskaźników do składowych klas nie
dotyczy statycznych składowych.
• Wskaźnik do statycznej składowej jest traktowany tak jak zwykły
składnik.
• Przykład 1:
class CLock
{
public:
static double tick_per_sec;
// …
double *p_tick= &Clock::tick_per_sec;

• Użycie:
*p_tick=18.2;
• Przykład 2:
void (*wsk_f)(void) = String::switch_stan;
• Użycie:
(*wsk_f)();


Slide 12

Modyfikator const - możliwości
• Słowo kluczowe const poprzedzające nazwę zmiennej wskazuje, że
ta zmienna jest stałą i nie może być modyfikowana w programie.
• Jeżeli argumentem funkcji jest wskaźnik zadeklarowany jako jako
const, to funkcja nie może zmieniać zawartości wskazywanej przez
ten wskaźnik:
size_t strlen( const char *string );
typedef _W64 unsigned int
size_t;
• Inicjalizacja pól klas z atrybutem const:
class Ala
{
const int z[3];
}Ula[2]={{{1,3,4}},{{3,2,5}}};
• Inicjalizacja jest możliwa tylko w linii definicji klasy. Potem jest już
za późno.
• Inicjalizacji pól typu const nie można już dokonać w konstruktorze.
Za późno .


Slide 13

Funkcje składowe z atrybutem const
• Jeżeli funkcja składowa nie zmienia danych klasy, można ją
zadeklarować jako const (z atrybutem const).
class String
{
private:
int len;
// …
public:
int length(void) const;
// …
};

int String::length(void) const
{
return len;
}


Slide 14

Przykład

..\..\Visual Studio Projects\test0\test0.sln

• punkt1.cpp
• Konstruktor i destruktor wywołują funkcję print z atrybutem
const.
• Funkcje set i move pozwalają na ustawianie i przesuwanie punktów.
Funkcje te mają domniemane argumenty. Domniemane argumenty są
w deklaracjach.
• W segmencie main są trzy obiekty z modyfikatorem const
• A[n]- tablica obiektów typu punkt
• Tablica wskaźników do funkcji składowych z argumentami:
void (punkt::*p_f1[2])(int,int) = {punkt::set,
punkt::move};
• Generacja losowa parametrów. Funkcje rand i srand
• Wskaźnik do funkcji składowej z atrybutem const:
void (punkt::*p_f)(void) const = punkt::print;
• Widać, że obiekty są usuwane w kolejności odwrotnej do zakładania.
• Proces zwalniania pamięci jest dokonywany w epilogu do programu.