c++builder 6. ćwiczenia zaawansowane full.pdf

(2591 KB) Pobierz
4
C++Builder 6. Ćwiczenia zaawansowane
Rozdział 6. Typy danych Windows.......................................................................................................................67
Rozdział 7.
Wątki.........................................................................................................................................................69
Wątki i procesy .............................................................................................................. 69
Funkcja _beginthread() ................................................................................................... 70
Funkcja _beginthreadNT() .............................................................................................. 72
Funkcja BeginThread() ................................................................................................... 77
Zmienne lokalne wątku................................................................................................... 80
Klasa TThread ............................................................................................................... 81
Metody.................................................................................................................... 81
Właściwości............................................................................................................. 82
Podsumowanie............................................................................................................... 84
Rozdział 8. Operacje na plikach ..........................................................................................................................85
Moduł SysUtils .............................................................................................................. 85
Windows API ................................................................................................................ 91
Klasa TMemoryStream................................................................................................... 98
Podsumowanie............................................................................................................. 101
Rozdział 9. Zmienne o typie modyfikowalnym w czasie wykonywania programu ....................103
Struktura TVarData ...................................................................................................... 103
Klasa TCustomVariantType .......................................................................................... 105
Moduł Variants ............................................................................................................ 107
Tablice wariantowe ...................................................................................................... 109
Podsumowanie............................................................................................................. 113
Rozdział 10. Liczby pseudolosowe.......................................................................................................................115
Losowanie z powtórzeniami .......................................................................................... 116
Losowanie bez powtórzeń............................................................................................. 119
Podsumowanie............................................................................................................. 124
Rozdział 11. Funkcje FPU..........................................................................................................................................125
Podsumowanie............................................................................................................. 128
Rozdział 12. Komponentowy model C++Buildera .......................................................................................129
Tworzymy nowy komponent......................................................................................... 129
Modyfikacja istniejącego komponentu z biblioteki VCL/CLX.......................................... 135
Podsumowanie............................................................................................................. 138
3.
Przeładowywanie
operatorów
Rozdział
Język C++ udostępnia programistom niezwykle wydajne narzędzie w postaci mo liwo-
ści przeładowywania (określania nowych działań) wybranych operatorów.
Przeładowywanie (przedefiniowywanie) operatorów umo liwia rozszerzenie obszaru
zastosowań wybranego operatora na elementy niezdefiniowanej wcześniej unikalnej klasy.
Projektując algorytm nowego działania wybranego operatora, nale y skorzystać ze spe-
cjalnej funkcji o zastrze onej nazwie
QRGTCVQT
:
QRGTCVQT U[ODQN QRGTCVQTC RCTCOGVT[ QRELQPCNPKG
]
KPUVTWMELG
_
Zapis ten oznacza, i , na przykład, najprostsza funkcja opisująca nowy algorytm odejmowa-
nia (nowy sposób działania unarnego operatora odejmowania ) będzie mogła przybrać
następującą postać:
QRGTCVQT RCTCOGVT[ ] KPUVTWMELG _
Reguły C++ umo liwiają przeładowywanie praktycznie wszystkich operatorów, za wy-
jątkiem czterech, dla których nie jest mo liwe zdefiniowanie nowych działań:
operatora kropki umo liwiającego uzyskiwanie bezpośredniego dostępu
do pół struktur i klas,

operatora wskazującego wybrany element klasy,
operatora rozró niania zakresu,
!
operatora warunkowego.
40
C++Builder 6. Ćwiczenia zaawansowane
Przeładowywanie jednoargumentowych
operatorów ++ oraz ––
Jako przykład praktycznego wykorzystania przeładowanego operatora postinkrementacji
posłu y nam sytuacja zliczania elementów ciągu znaków wprowadzonych z klawiatury.
W celu przeładowania jednoargumentowego operatora
w pierwszej kolejności musimy
zaprojektować odpowiednią funkcję operatorową. Ka da funkcja operatorowa powinna
mieć mo liwość wykonywania odpowiednich operacji na właściwych egzemplarzach
klasy (lub obiektu), inaczej mówiąc, powinna w stosunku do odpowiedniej klasy posiadać
status funkcji zaprzyjaźnionej lub być normalną metodą w klasie. Zaprojektujemy prostą
klasę o nazwie
EQWPVGT
(licznik):
ENCUU EQWPVGT
]
RWDNKE
KPV PWODGT
EQWPVGT ]VJKU PWODGT _
EQWPVGT QRGTCVQT ]VJKU PWODGT TGVWTP

VJKU_

_ CFF
Poniewa celem naszym będzie zwiększanie w odpowiedni sposób (postinkrementowanie)
wartości pola
PWODGT
egzemplarza
CFF
klasy
EQWPVGT
, funkcja operatorowa przybierze
nieskomplikowaną postać:
EQWPVGT QRGTCVQT ]VJKU PWODGT TGVWTP

VJKU_

Zauwa my, i funkcja ta, będąc normalną metodą w klasie, nie posiada jawnych argu-
mentów i w momencie wywołania otrzymuje
niejawny
wskaźnik
VJKU
do własnego eg-
zemplarza klasy. Dzięki posiadaniu niejawnego wskaźnika
VJKU
funkcja ma mo liwość
postinkrementowania wartości pola
PWODGT
własnego egzemplarza klasy.
Dzięki instrukcji:
TGVWTP

VJKU

funkcja operatorowa jawnie zwraca wskaźnik do zmodyfikowanego egzemplarza
CFF
klasy
EQWPVGT
.
Ćwiczenie 3.1.
Ka da funkcja składowa klasy otrzymuje niejawnie argument w postaci wskaźnika do
obiektu, który ją wywołał, i do którego uzyskuje się dostęp, wykorzystując słowo kluczowe
(wskaźnik)
VJKU
. Funkcje składowe przeładowywanych operatorów jednoargumentowych
nie potrzebują adnych jawnie zadeklarowanych parametrów formalnych. Jedynym argu-
mentem, którego nale y u yć, jest wskaźnik
VJKU
, będący w rzeczywistości wskaźnikiem
do egzemplarza klasy, a nie jego kopią. Konsekwencją tego jest fakt, i wszystkie modyfi-
kacje wykonane za jego pośrednictwem przez funkcję operatora modyfikują zawartość
wywoływanego egzemplarza klasy. Przykład wykorzystania funkcji
QRGTCVQT
prze-
ładowanego operatora
w celu zliczania znaków wprowadzanych z klawiatury zamiesz-
czono na listingu 3.1. Koniec ciągu wprowadzanych znaków oznaczamy klawiszem
Esc.
Rozdział 3.
Przeładowywanie operatorów
41
Listing 3.1.
Główny moduł Unit_13.cpp projektu Projekt_13.bpr wykorzystującego normalną funkcję składową
przeładowanego operatora jednoargumentowego ++. W przedstawionym algorytmie zrezygnowano
z u ywania niejawnych wskaźników this
KPENWFG KQUVTGCOJ
KPENWFG EQPKQJ
RTCIOC JFTUVQR
ENCUU EQWPVGT
]
RWDNKE
KPV PWODGT
EQWPVGT ]PWODGT _
EQWPVGT QRGTCVQT
RQUVKPMTGOGPVCELC RQNC PWODGT
]PWODGT TGVWTP

VJKU_

_ CFF
KPV OCKP
]
EJCT EJ
EQWV 2QFCL KOKú K PC\YKUMQ
#D[ \CMQ E\[è PCEK PKL ='UE? K ='PVGT? GPFN
YJKNG
]
EKP
EJ
KH EJ Z$ DTGCM
\NKE\CPKG \PCMÎY OGVQFæ RTGKPMTGOGPVCELK
CFF
_
EQWV 9RTQYCF\QPQ
CFFPWODGT
\PCMK \PCMÎY
IGVEJ
TGVWTP
_
Analizując powy sze zapisy, warto zwrócić uwagę na pewien szczegół. Mianowicie jawny
wskaźnik
VJKU
wskazuje własny obiekt funkcji. Je eli jednak za ądamy, aby funkcja
uzyskiwała dostęp nie do pola własnego egzemplarza klasy, ale do pola obiektu przeka-
zywanego jej jako argument, zawsze mo emy nadać jej status
HTKGPF
, czyli funkcji za-
przyjaźnionej. Funkcje z nadanym statusem
HTKGPF
będą bez problemu uzyskiwać dostęp
do pól klasy, nie będąc przy tym traktowane jako zwykłe metody w klasie.
Ćwiczenie 3.2.
Proces przeładowywania operatorów jednoargumentowych mo e przebiegać z wykorzy-
staniem
funkcji zaprzyjaźnionych
(ang.
friend functions).
Nale y jednak zwrócić uwagę, i
stosując taką technikę przeładowywania operatorów powinniśmy w odpowiedni sposób
u ywać parametrów odwołaniowych po to, aby kompilator przekazywał funkcji opera-
tora adres, a nie kopię egzemplarza klasy, który ją wywołał, umo liwiając zmianę jego
zawartości. W przeciwieństwie do normalnych funkcji składowych funkcje zaprzyjaźnione
nie mogą otrzymywać wskaźnika
VJKU
(niezale nie od tego, czy traktowany będzie jako
wskaźnik jawny czy niejawny), co powoduje, i nie są w stanie określić wywołującego
je egzemplarza klasy, tak jak pokazano to na listingu 3.2.
Zgłoś jeśli naruszono regulamin