Professional Documents
Culture Documents
PRZYKADOWY ROZDZIA
SPIS TRECI
KATALOG KSIEK
KATALOG ONLINE
ZAMW DRUKOWANY KATALOG
TWJ KOSZYK
DODAJ DO KOSZYKA
CENNIK I INFORMACJE
ZAMW INFORMACJE
O NOWOCIACH
ZAMW CENNIK
CZYTELNIA
FRAGMENTY KSIEK ONLINE
Wydawnictwo Helion
ul. Chopina 6
44-100 Gliwice
tel. (32)230-98-63
e-mail: helion@helion.pl
Thinking in C++.
Edycja polska
Autor: Bruce Eckel
Tumaczenie: Piotr Imiela
ISBN: 83-7197-709-3
Tytu oryginau: Thinking in C++
Format: B5, stron: 642
Przykady na ftp: 247 kB
Spis treci
Wstp ............................................................................................. 13
Co nowego w drugim wydaniu?........................................................................................13
Zawarto drugiego tomu ksiki ...............................................................................14
Skd wzi drugi tom ksiki? ...................................................................................14
Wymagania wstpne .........................................................................................................14
Nauka jzyka C++.............................................................................................................15
Cele....................................................................................................................................16
Zawarto rozdziaw .......................................................................................................17
wiczenia ..........................................................................................................................21
Rozwizania wicze..................................................................................................21
Kod rdowy....................................................................................................................21
Standardy jzyka ...............................................................................................................22
Obsuga jzyka............................................................................................................23
Bdy .................................................................................................................................23
Okadka .............................................................................................................................24
Spis treci
7
Wprowadzenie do typw danych ....................................................................................108
Podstawowe typy wbudowane..................................................................................109
bool, true i false.........................................................................................................110
Specyfikatory ............................................................................................................111
Wprowadzenie do wskanikw ................................................................................112
Modyfikacja obiektw zewntrznych .......................................................................115
Wprowadzenie do referencji .....................................................................................117
Wskaniki i referencje jako modyfikatory................................................................118
Zasig ..............................................................................................................................120
Definiowanie zmiennych w locie ..........................................................................120
Specyfikacja przydziau pamici.....................................................................................122
Zmienne globalne......................................................................................................122
Zmienne lokalne........................................................................................................124
static ..........................................................................................................................124
extern.........................................................................................................................126
Stae...........................................................................................................................127
volatile.......................................................................................................................129
Operatory i ich uywanie ................................................................................................129
Przypisanie................................................................................................................130
Operatory matematyczne ..........................................................................................130
Operatory relacji .......................................................................................................131
Operatory logiczne....................................................................................................131
Operatory bitowe ......................................................................................................132
Operatory przesuni ................................................................................................133
Operatory jednoargumentowe...................................................................................135
Operator trjargumentowy........................................................................................136
Operator przecinkowy...............................................................................................137
Najczstsze puapkizwizane z uywaniem operatorw ..........................................137
Operatory rzutowania................................................................................................138
Jawne rzutowanie w C++..........................................................................................139
sizeof samotny operator .......................................................................................143
Sowo kluczowe asm.................................................................................................143
Operatory dosowne ..................................................................................................144
Tworzenie typw zoonych ...........................................................................................144
Nadawanie typom nowych nazw za pomoc typedef ...............................................144
czenie zmiennych w struktury ..............................................................................145
Zwikszanie przejrzystoci programwza pomoc wylicze ...................................148
Oszczdzanie pamici za pomoc unii .....................................................................150
Tablice.......................................................................................................................151
Wskazwki dotyczce uruchamiania programw...........................................................159
Znaczniki uruchomieniowe.......................................................................................160
Przeksztacanie zmiennych i wyrae w acuchy ...................................................162
Makroinstrukcja assert( ) jzyka C ...........................................................................162
Adresy funkcji .................................................................................................................163
Definicja wskanika do funkcji ................................................................................163
Skomplikowane deklaracje i definicje ......................................................................164
Wykorzystywanie wskanikw do funkcji ...............................................................165
Tablice wskanikw do funkcji ................................................................................166
Make zarzdzanie rozczn kompilacj....................................................................167
Dziaanie programu make .........................................................................................168
Pliki makefile uywane w ksice ............................................................................171
Przykadowy plik makefile .......................................................................................171
Podsumowanie ................................................................................................................173
wiczenia ........................................................................................................................173
Spis treci
9
Przykadowe przecienie ...............................................................................................253
Unie .................................................................................................................................255
Argumenty domylne ......................................................................................................258
Argumenty-wypeniacze ...........................................................................................259
Przecianiekontra argumenty domylne........................................................................260
Podsumowanie ................................................................................................................264
wiczenia ........................................................................................................................265
10
Spis treci
11
Zmiany w prezentowanych wczeniej przykadach ........................................................443
Usuwanie wskanika void* jest prawdopodobnie bdem .......................................443
Odpowiedzialno za sprztanie wskanikw ..........................................................445
Klasa Stash przechowujca wskaniki......................................................................445
Operatory new i delete dla tablic.....................................................................................450
Upodabnianie wskanika do tablicy .........................................................................451
Brak pamici ...................................................................................................................451
Przecianie operatorw new i delete .............................................................................452
Przecianie globalnych operatorw new i delete ....................................................453
Przecianie operatorw new i delete w obrbie klasy .................................................455
Przecianie operatorw new i deletew stosunku do tablic......................................458
Wywoania konstruktora...........................................................................................460
Operatory umieszczania new i delete .......................................................................461
Podsumowanie ................................................................................................................463
wiczenia ........................................................................................................................463
12
Skorowidz...................................................................................... 627
Rozdzia 5.
Ukrywanie implementacji
Typowa biblioteka skada si w jzyku C ze struktury i kilku doczonych funkcji,
wykonujcych na niej operacje. Zapoznalimy si ze sposobem, w jaki jzyk C++
grupuje funkcje, zwizane ze sob pojciowo, i czy je literalnie. Dokonuje tego
umieszczajc deklaracje funkcji w obrbie zasigu struktury, zmieniajc sposb,
w jaki funkcje te s wywoywane w stosunku do tej struktury, eliminujc przekazywanie adresu struktury jako pierwszego argumentu i dodajc do programu nazw nowego typu (dziki czemu nie trzeba uywa sowa kluczowego typedef w stosunku
do identyfikatora struktury).
Wszystko to zapewnia wiksz wygod pozwala lepiej zorganizowa kod i uatwia
zarwno jego napisanie, jak i przeczytanie. Warto jednak poruszy jeszcze inne wane
zagadnienia, zwizane z atwiejszym tworzeniem bibliotek w jzyku C++ w szczeglnoci s to kwestie, dotyczce bezpieczestwa i kontroli. W niniejszym rozdziale zapoznamy si bliej z kwestiami ogranicze dotyczcych struktur.
Okrelanie ogranicze
W kadej relacji istotne jest okrelenie granic, respektowanych przez wszystkie zaangaowane w ni strony. Tworzc bibliotek, ustanawiasz relacj z klientem-programist,
uywajcym twojej biblioteki do zbudowania aplikacji lub utworzenia innej biblioteki.
W strukturach dostpnych w jzyku C, podobnie jak w wikszoci elementw tego
jzyka, nie obowizuj adne reguy. Klienci-programici mog postpi dowolnie ze
struktur i nie ma adnego sposobu, by wymusi na nich jakiekolwiek szczeglne zachowania. Na przykad mimo wanoci funkcji o nazwach initialize( ) i cleanup( )
(wskazanej w poprzednim rozdziale), klient-programista moe w ogle ich nie wywoa (lepsze rozwizanie tej kwestii zaprezentujemy w nastpnym rozdziale). W jzyku C nie ma adnego sposobu zapobieenia temu, by klienci-programici operowali
bezporednio na niektrych skadowych struktur. Wszystko ma charakter jawny.
212
213
$%)&'!(
&'!
") "
*
*+"
*
*,,"
*
*-
+.+/"
&'"
&'"
(0
214
Specyfikator protected
Ostatnim specyfikatorem dostpu jest protected. Jego znaczenie jest zblione do specyfikatora private, z jednym wyjtkiem, ktry nie moe zosta jeszcze teraz wyjaniony struktury dziedziczce (ktre nie posiadaj dostpu do skadowych prywatnych) maj zagwarantowany dostp do skadowych oznaczonych specyfikatorem
protected. Zostanie to wyjanione w rozdziale 14., przy okazji wprowadzenia pojcia
dziedziczenia. Tymczasowo mona przyj, e specyfikator protected dziaa podobnie do specyfikatora private.
Przyjaciele
Co zrobi w sytuacji, gdy chcemy jawnie udzieli pozwolenia na dostp funkcji, niebdcej skadow biecej struktury? Uzyskuje si to, deklarujc funkcj za pomoc sowa
kluczowego friend (przyjaciel) wewntrz deklaracji struktury. Wane jest, by deklaracja
friend wystpowaa w obrbie deklaracji struktury, poniewa programista (i kompilator),
czytajc deklaracj struktury, musi pozna wszystkie zasady dotyczce wielkoci i zachowania tego typu danych. A niezwykle wan zasad, obowizujc w kadej relacji,
stanowi odpowied na pytanie: Kto ma dostp do mojej prywatnej implementacji?.
To sama struktura okrela, ktry kod ma dostp do jej skadowych. Nie ma adnego magicznego sposobu wamania si z zewntrz, jeeli nie jest si przyjacielem nie
mona zadeklarowa nowej klasy, twierdzc: Cze, jestem przyjacielem Boba! i spodziewajc si, e zapewni to dostp do prywatnych i chronionych skadowych klasy Bob.
Wolno zadeklarowa jako przyjaciela funkcj globaln; moe nim by rwnie
skadowa innej struktury albo nawet caa struktura zadeklarowana z uyciem sowa
kluczowego friend. Poniej zamieszczono przykad:
8%
%%
%
9
&
'
:"
;!
$%&:<'"
("
:!9
$
"
$%
&'"
%$%3&:<5'"
3
%$%;&:<'"
%=%=
%>"
215
$%:
&'!
*"
(
$%3&:<?5'!
?@A*"
(
$%;&:<?'!
?@A*.B"
(
>!
$
"
$%
&'"
$%3&:<?'"
("
$%>
&'!
*//"
(
$%>3&:<?'!
?@AC*"
(
$%#&'!
:?"
?
*+")2%%
(
&'!
:?"
>"
3&D?'"
(0
216
Przekazujc adres struktury X, kompilator pozwala na utworzenie niepenej specyfikacji typu X, umieszczonej przed deklaracj Y::f(X*). Uzyskuje si j za pomoc deklaracji:
:"
Deklaracja ta informuje kompilator, e istnieje struktura o podanej nazwie, wic mona odwoa si do niej, dopki nie jest na jej temat potrzebna adna dodatkowa wiedza, poza nazw.
Potem funkcja Y::f(X*) w strukturze X moe by ju bez problemu zadeklarowana
jako przyjaciel. W razie prby zadeklarowania jej, zanim kompilator napotka pen
specyfikacj klasy Y, nastpioby zgoszenie bdu. Jest to cecha zapewniajca bezpieczestwo i spjno, a take zapobiegajca bdom.
Zwr uwag na dwie pozostae funkcje zadeklarowane z uyciem sowa kluczowego
friend. Pierwsza z nich deklaruje jako przyjaciela zwyk funkcj globaln g( ).
Funkcja ta nie zostaa jednak wczeniej zadeklarowana w zasigu globalnym! Okazuje si, e taki sposb uycia deklaracji friend moe zosta wykorzystany do rwnoczesnego zadeklarowania funkcji i nadania jej statusu przyjaciela. Dotyczy to rwnie caych struktur. Deklaracja:
%>"
jest niepen specyfikacj typu struktury Z, nadajc rwnoczenie caej tej strukturze
status przyjaciela.
Zagniedeni przyjaciele
Utworzenie struktury zagniedonej nie zapewnia jej automatycznie prawa dostpu
do skadowych prywatnych. Aby to osign, naley postpi w szczeglny sposb:
najpierw zadeklarowa (nie definiujc) struktur zagniedon, nastpnie zadeklarowa j, uywajc sowa kluczowego friend, a na koniec zdefiniowa struktur.
Definicja struktury musi by oddzielona od deklaracji friend, bo w przeciwnym
przypadku kompilator nie uznaby jej za skadow struktury. Poniej zamieszczono
przykad takiego zagniedenia struktury:
78%
>3E%EF
F
G
%HA
G
%H3A&'
3%"
*I"
J
%!
$
KL"
$%
&'"
"
%"
!
217
218
219
Klasy
Kontrola dostpu jest czsto okrelana mianem ukrywania implementacji. Umieszczenie funkcji w strukturach (czsto nazywane kapsukowaniem1) tworzy typy danych, posiadajce zarwno cechy, jak i zachowanie. Jednake kontrola dostpu wy1
220
221
)!
55"
&'"
$%3&'"
("
)&'!
CC"
(
$%)3&'!
***"
(
&'!
"
) "
&'"
3&'"
&'"
3&'"
(0
Przemawia za tym argument, e czytelnikowi takiego kodu wydaje si bardziej logiczne czytanie najpierw interesujcych go skadowych, a nastpnie pominicie
wszystkiego, co zostao oznaczone jako prywatne. Faktycznie, wszystkie pozostae
skadowe naley zadeklarowa w obrbie klasy jedynie dlatego, e kompilator musi
zna wielkoci obiektw, by mg przydzieli im we waciwy sposb pami. Istotna
jest take moliwo zagwarantowania spjnoci klasy.
Jednak w przykadach wystpujcych w ksice skadowe prywatne bd znajdoway
si na pocztku deklaracji klasy, jak poniej:
:!
$%O&'"
O"
$%O&'"
("
222
Funkcja inflate( ) zostaa okrelona jako prywatna, poniewa jest ona uywana wycznie przez funkcj add( ); stanowi zatem cz wewntrznego mechanizmu funkcjonowania klasy, a nie jej interfejsu. Oznacza to, e w przyszoci mona bdzie
zmieni wewntrzn implementacj, uywajc innego systemu zarzdzania pamici.
Powysza zawarto pliku nagwkowego jako jedyna poza jego nazw ulega
modyfikacji w powyszym przykadzie. Zarwno plik zawierajcy implementacj, jak
i plik testowy pozostay takie same.
223
Podobnie jak poprzednio, implementacja nie ulega w tym przypadku zmianie, nie zostaa wic w tym miejscu powtrnie przytoczona. Plik zawierajcy program testowy
rwnie si nie zmieni. Zostaa jedynie zmodyfikowana moc, uzyskana dziki interfejsowi klasy. Istotn korzyci, wynikajc z kontroli dostpu, jest uniemoliwienie
przekraczania granic podczas tworzenia programu. W rzeczywistoci jedynie kompilator posiada informacje dotyczce poziomu zabezpiecze poszczeglnych skadowych klasy. Nie istnieje adna informacja umoliwiajca kontrol dostpu, ktra byaby doczana do nazwy skadowej klasy, a nastpnie przekazywana programowi
czcemu. Caa kontrola zabezpiecze jest dokonywana przez kompilator i nie zostaje przerwana w czasie wykonywania programu.
Zwr uwag na to, e interfejs prezentowany klientowi-programicie rzeczywicie
odpowiada teraz rozwijanemu w d stosowi. Jest on obecnie zaimplementowany
w postaci powizanej listy, lecz mona to zmieni, nie modyfikujc elementw wykorzystywanych przez klienta-programist, a zatem (co waniejsze) rwnie ani jednego
wiersza napisanego przez niego kodu.
Klasy-uchwyty
Kontrola dostpu w jzyku C++ pozwala na oddzielenie interfejsu od implementacji, jednak ukrycie implementacji jest tylko czciowe. Kompilator musi nadal widzie deklaracje wszystkich elementw obiektu po to, by mg poprawnie je tworzy i odpowiednio
224
obsugiwa. Mona wyobrazi sobie jzyk programowania, ktry wymagaby okrelenia jedynie publicznego interfejsu obiektu, pozwalajc na ukrycie jego prywatnej
implementacji. Jednake jzyk C++ dokonuje kontroli typw statycznie (w czasie
kompilacji), zawsze gdy jest to tylko moliwe. Oznacza to, e programista jest powiadamiany o bdach moliwie jak najszybciej, a take to, e program jest bardziej
efektywny. Jednak doczenie prywatnej implementacji pociga za sob dwa skutki
implementacja jest widoczna, nawet jeeli nie ma do niej atwego dostpu, a ponadto moe ona wywoywa niepotrzebnie powtrn kompilacj programu.
Ukrywanie implementacji
W przypadku niektrych projektw nie wolno dopuci do tego, by ich implementacja
bya widoczna dla klienta-programisty. Plik nagwkowy biblioteki moe zawiera informacje o znaczeniu strategicznym, ktrych firma nie zamierza udostpnia konkurentom.
By moe pracujesz nad systemem, w ktrym istotn kwesti stanowi bezpieczestwo
na przykad algorytm szyfrowania i nie chcesz umieszcza w pliku nagwkowym
informacji, ktre mogyby uatwi zamanie kodu. Albo zamierzasz umieci swoj bibliotek we wrogim rodowisku, w ktrym programici i tak bd odwoywa si do
prywatnych skadowych klasy wykorzystujc wskaniki i rzutowanie. We wszystkich
takich przypadkach lepiej skompilowa rzeczywist struktur klasy wewntrz pliku, zawierajcego jej implementacj, ni ujawnia j w pliku nagwkowym.
225
stanowi niepen specyfikacj typu albo deklaracj klasy (definicja klasy zawieraaby
jej ciao). Informuje ona kompilator, e Cheshire jest nazw struktury, lecz nie dostarcza adnych szczegw na jej temat. Informacja wystarcza jedynie do utworzenia
wskanika do tej struktury nie mona utworzy obiektu, dopki nie zostanie udostpnione jej ciao. W przypadku zastosowania tej techniki ciao to jest ukryte w pliku
zawierajcym implementacj:
J%
!1(
W
#
G
%FJ%
#F
G
%F
S
#F
9
#
J%
##!
"
("
$%J%
&'!
*##"
@A*"
(
$%J%
&'!
%
"
(
J%
%&'!
@A"
(
$%J%
#3&?'!
@A*?"
(0
226
Cheshire jest struktur zagniedon, musi wic ona zosta zdefiniowana w zasigu
klasy:
J%
##!
Jedyn rzecz, do ktrej ma dostp klient, jest publiczny interfejs klasy. Dopki wic
zmienia si jedynie jej implementacja, powyszy plik nie bdzie nigdy wymaga powtrnej kompilacji. Tak wic, mimo e nie jest to doskonay sposb ukrycia implementacji, stanowi on w tej dziedzinie ogromny krok naprzd.
Podsumowanie
Kontrola dostpu w jzyku C++ zapewnia programicie cisy nadzr nad utworzon
przez siebie klas. Uytkownicy klasy widz w przejrzysty sposb, czego mog uywa, a co powinni zignorowa. Jeszcze waniejsza jest moliwo gwarancji, e aden klient-programista nie bdzie uzaleniony od jakiejkolwiek czci kodu tworzcego wewntrzn implementacj klasy. Dziki temu twrca klasy moe zmieni
wewntrzn implementacj, wiedzc e aden z klientw-programistw nie zostanie
zmuszony do wprowadzania jakichkolwiek modyfikacji w swoim programie, poniewa nie ma on dostpu do tej czci klasy.
Majc moliwo zmiany wewntrznej implementacji, mona nie tylko udoskonali
swj projekt, ale rwnie pozwoli sobie na popenianie bdw. Bez wzgldu na to,
jak skrupulatnie zaplanuje si wszystko i wykona, i tak dojdzie do pomyek. Wiedza,
e popenianie takich bdw jest stosunkowo bezpieczne, umoliwia eksperymentowanie, efektywniejsz nauk i szybsze zakoczenie projektu.
227
Publiczny interfejs klasy jest tym, co widzi klient-programista, naley wic we waciwy sposb przemyle go w trakcie analizy i projektowania. Lecz nawet on pozostawia pewn moliwo wprowadzania zmian. Jeeli posta interfejsu nie zostanie
od razu gruntownie przemylana, mona uzupeni go o nowe funkcje, pod warunkiem, e nie zostan z niego usunite te spord funkcji, ktre zostay ju uyte przez
klientw-programistw.
wiczenia
Rozwizania wybranych wicze znajduj si w dokumencie elektronicznym: The
Thinking in C++ Annotated Solution Guide, ktry mona pobra za niewielk opat
z witryny http://www.BruceEckel.com.
1. Utwrz klas posiadajc dane skadowe publiczne, prywatne oraz chronione.
ulokuj klas Egg. Kada z klas powinna posiada funkcj skadow display( ).
W funkcji main( ) utwrz obiekty kadej z klas i wywoaj dla kadego z nich
funkcj display( ).
7. Zmodyfikuj poprzednie wiczenie w taki sposb, aby klasy Nest i Egg
zawieray dane prywatne. Okrel przyjaci tych klas, tak aby do ich danych
prywatnych miay dostp klasy, w ktrych s one zagniedone.
228