Cyfroteka.pl

klikaj i czytaj online

Cyfro
Czytomierz
00064 007765 10468590 na godz. na dobę w sumie
Język C++. Koncepcje i techniki programowania - książka
Język C++. Koncepcje i techniki programowania - książka
Autor: , Liczba stron: 392
Wydawca: Helion Język publikacji: polski
ISBN: 83-7361-702-7 Data wydania:
Lektor:
Kategoria: ebooki >> komputery i informatyka >> programowanie >> c++ - programowanie
Porównaj ceny (książka, ebook, audiobook).

Język C++ to najpopularniejszy obecnie język programowania. Jego podstawowe zalety -- przejrzysta składnia, niewielka ilość słów kluczowych i szeroki wachlarz możliwości -- przysporzyły mu wielu zwolenników. Na rynku dostępnych jest wiele książek o programowaniu w C++, jednak większość z nich zawiera sposoby rozwiązywania konkretnych problemów i zadań programistycznych. Niewiele książek koncentruje się na założeniach, na których opiera się programowanie w języku C++.

W książce 'Język C++. Koncepcje i techniki programowania' autorzy skoncentrowali się na kluczowych technikach programowania w C++. Jednak nie przedstawiają ich w formie odpowiedzi na pytania 'jak to zrobić', ale 'dlaczego robimy to tak, a nie inaczej'. Opisują szeroki wachlarz idei i technik programowania w C++ począwszy od szczegółowych przykładów kodu, a skończywszy na zasadach i filozofii projektowania.

Dzięki tej książce nauczysz się nie tylko przestrzegać reguł języka C++, ale także myśleć w tym języku podczas pracy nad programem.

O autorach:
Andrew Koenig jest członkiem działu badającego systemy oprogramowania w Shannon Laboratory firmy AT&T oraz redaktorem projektu komitetów standaryzacyjnych języka C++. [więcej...\

Barbara Moo jest konsultantką z dwudziestoletnim doświadczeniem programistycznym, zarządzała projektem pierwszego kompilatora C++. [więcej...\

Znajdź podobne książki Ostatnio czytane w tej kategorii

Darmowy fragment publikacji:

IDZ DO IDZ DO PRZYK£ADOWY ROZDZIA£ PRZYK£ADOWY ROZDZIA£ SPIS TREĎCI SPIS TREĎCI KATALOG KSI¥¯EK KATALOG KSI¥¯EK KATALOG ONLINE KATALOG ONLINE ZAMÓW DRUKOWANY KATALOG ZAMÓW DRUKOWANY KATALOG TWÓJ KOSZYK TWÓJ KOSZYK DODAJ DO KOSZYKA DODAJ DO KOSZYKA CENNIK I INFORMACJE CENNIK I INFORMACJE ZAMÓW INFORMACJE ZAMÓW INFORMACJE O NOWOĎCIACH O NOWOĎCIACH ZAMÓW CENNIK ZAMÓW CENNIK CZYTELNIA CZYTELNIA FRAGMENTY KSI¥¯EK ONLINE FRAGMENTY KSI¥¯EK ONLINE Wydawnictwo Helion ul. Chopina 6 44-100 Gliwice tel. (32)230-98-63 e-mail: helion@helion.pl Jêzyk C++. Koncepcje i techniki programowania Autor: Andrew Koenig, Barbara Moo T³umaczenie: Jaros³aw Dobrzañski ISBN: 83-7361-702-7 Tytu³ orygina³u: Ruminations on C++ Format: B5, stron: 362 Jêzyk C++ to najpopularniejszy obecnie jêzyk programowania. Jego podstawowe zalety — przejrzysta sk³adnia, niewielka iloġæ s³ów kluczowych i szeroki wachlarz mo¿liwoġci — przysporzy³y mu wielu zwolenników. Na rynku dostêpnych jest wiele ksi¹¿ek o programowaniu w C++, jednak wiêkszoġæ z nich zawiera sposoby rozwi¹zywania konkretnych problemów i zadañ programistycznych. Niewiele ksi¹¿ek koncentruje siê na za³o¿eniach, na których opiera siê programowanie w jêzyku C++. W ksi¹¿ce „Jêzyk C++. Koncepcje i techniki programowania” autorzy skoncentrowali siê na kluczowych technikach programowania w C++. Jednak nie przedstawiaj¹ ich w formie odpowiedzi na pytania „jak to zrobiæ”, ale „dlaczego robimy to tak, a nie inaczej”. Opisuj¹ szeroki wachlarz idei i technik programowania w C++ pocz¹wszy od szczegó³owych przyk³adów kodu, a skoñczywszy na zasadach i filozofii projektowania. • Tworzenie klas • Uchwyty klas • Zasady projektowania obiektowego • Szablony i iteratory • Stosowanie bibliotek • Projektowanie bibliotek • Techniki programowania Dziêki tej ksi¹¿ce nauczysz siê nie tylko przestrzegaæ regu³ jêzyka C++, ale tak¿e myġleæ w tym jêzyku podczas pracy nad programem. Spis treści Wstęp ...................................................w.......................................... 11 Wprowadzenie ...................................................w.............................. 15 0.1. Podejście pierwsze...................................................ś............................................... 15 0.2. Jak to zrobić bez klas? ...................................................ś......................................... 18 0.3. Dlaczego w C++ było łatwiej?...................................................ś............................. 19 0.4. Bardziej rozbudowany przykład ...................................................ś.......................... 20 0.5. Wnioski ...................................................ś...................................................ś............ 20 Część I Motywacja ...................................................t..................23 Rozdział 1. Dlaczego używam C++? ...................................................w................ 25 1.1. Problem ...................................................ś...................................................ś............ 25 1.2. Historia i kontekst...................................................ś................................................ 26 1.3. Automatyczna dystrybucja oprogramowania...................................................ś....... 27 1.4. Czas na C++ ...................................................ś...................................................ś..... 30 1.5. Oprogramowanie z odzysku ...................................................ś................................ 34 1.6. Postscriptum ...................................................ś...................................................ś..... 35 Rozdział 2. Dlaczego pracuję nad rozwojem C++?............................................... 37 2.1. Sukces małych projektów ...................................................ś.................................... 37 2.2. Abstrakcja...................................................ś...................................................ś......... 39 2.3. Maszyny powinny pracować dla ludzi...................................................ś................. 42 Rozdział 3. Życie w prawdziwym świecie...................................................w......... 43 Część II Klasy i dziedziczenie...................................................t....49 Rozdział 4. Lista kontrolna dla autorów klas ...................................................w... 51 Rozdział 5. Klasy surogatów ...................................................w........................... 61 5.1. Problem ...................................................ś...................................................ś............ 61 5.2. Rozwiązanie klasyczne...................................................ś........................................ 62 5.3. Wirtualne funkcje kopiujące...................................................ś................................ 63 5.4. Definiowanie klasy surogatu ...................................................ś............................... 64 5.5. Podsumowanie...................................................ś...................................................ś.. 67 Rozdział 6. Uchwyty — część 1. ...................................................w.................... 69 6.1. Problem ...................................................ś...................................................ś............ 69 6.2. Prosta klasa...................................................ś...................................................ś....... 70 6.3. Przyłączanie uchwytu ...................................................ś.......................................... 72 6 Język C++. Koncepcje i techniki programowania 6.4. Dostęp do obiektu...................................................ś................................................ 72 6.5. Prosta implementacja...................................................ś........................................... 73 6.6. Uchwyty z licznikami użycia...................................................ś............................... 74 6.7. Kopiowanie przy zapisie...................................................ś...................................... 76 6.8. Omówienie ...................................................ś...................................................ś....... 77 Rozdział 7. Uchwyty — część 2. ...................................................w.................... 79 7.1. Przypomnienie...................................................ś...................................................ś.. 80 7.2. Separowanie licznika użycia...................................................ś................................ 81 7.3. Abstrahowanie liczników użycia ...................................................ś......................... 82 7.4. Funkcje dostępowe i kopiowanie przy zapisie...................................................ś..... 84 7.5. Omówienie ...................................................ś...................................................ś....... 85 Rozdział 8. Program obiektowy ...................................................w....................... 87 8.1. Problem ...................................................ś...................................................ś............ 87 8.2. Rozwiązanie obiektowe ...................................................ś....................................... 88 8.3. Klasy uchwytów ...................................................ś.................................................. 91 8.4. Rozwinięcie 1. — nowe operacje ...................................................ś........................ 94 8.5. Rozwinięcie 2. — nowe typy węzłów ...................................................ś................. 96 8.6. Refleksje...................................................ś...................................................ś...........98 Rozdział 9. Analiza ćwiczenia praktycznego — część 1. ..................................... 99 9.1. Problem ...................................................ś...................................................ś............ 99 9.2. Projektowanie interfejsu ...................................................ś.................................... 101 9.3. Kilka brakujących elementów ...................................................ś........................... 103 9.4. Testowanie interfejsu...................................................ś......................................... 104 9.5. Strategia...................................................ś...................................................ś.......... 104 9.6. Taktyka...................................................ś...................................................ś........... 105 9.7. Łączenie obrazów...................................................ś.............................................. 108 9.8. Wnioski ...................................................ś...................................................ś.......... 111 Rozdział 10. Analiza ćwiczenia praktycznego — część 2. ................................... 113 10.1. Strategia...................................................ś...................................................ś..........113 10.2. Korzystanie z możliwości struktury ...................................................ś.................. 125 10.3. Wnioski ...................................................ś...................................................ś.......... 128 Rozdział 11. Kiedy nie używać funkcji wirtualnych? ............................................ 131 11.1. Argumenty „za”...................................................ś................................................. 131 11.2. Argumenty „przeciw”...................................................ś........................................ 132 11.3. Szczególna rola destruktorów...................................................ś............................ 137 11.4. Podsumowanie...................................................ś...................................................ś 139 Część III Szablony ...................................................t...................141 Rozdział 12. Tworzenie klasy zasobnika ...................................................w.......... 143 12.1. Co jest w środku? ...................................................ś.............................................. 143 12.2. Co oznacza kopiowanie zasobnika? ...................................................ś.................. 144 12.3. Jak dostać się do elementów w zasobniku? ...................................................ś....... 147 12.4. Jak odróżnić odczyt od zapisu? ...................................................ś......................... 148 12.5. Jak poradzić sobie z rozrostem zasobnika?...................................................ś........ 150 12.6. Jakie operacje udostępnia zasobnik? ...................................................ś................. 151 12.7. Jakie są założenia związane z typem elementu zasobnika? .................................. 152 12.8. Zasobniki i dziedziczenie ...................................................ś.................................. 153 12.9. Projektowanie klasy „tablicopodobnej”...................................................ś............. 154 Spis treści 7 Rozdział 13. Dostęp do elementów zasobnika ...................................................w. 161 13.1. Imitowanie wskaźnika ...................................................ś....................................... 161 13.2. Dostęp do danych ...................................................ś.............................................. 163 13.3. Pozostałe problemy ...................................................ś........................................... 165 13.4. Pointer wskazujący const Array ...................................................ś........................ 169 13.5. Użyteczne dodatki ...................................................ś............................................. 170 Rozdział 14. Iteratory ...................................................w..................................... 175 14.1. Uzupełnianie klasy Pointer...................................................ś................................ 175 14.2. Co to jest iterator? ...................................................ś............................................. 178 14.3. Usuwanie elementu ...................................................ś........................................... 179 14.4. Usuwanie zasobnika ...................................................ś.......................................... 180 14.5. Inne względy projektowe...................................................ś................................... 181 14.6. Podsumowanie...................................................ś...................................................ś 182 Rozdział 15. Sekwencje...................................................w.................................. 183 15.1. Dzieło sztuki...................................................ś...................................................ś... 183 15.2. Stara, radykalna idea ...................................................ś......................................... 185 15.3. Może jeszcze kilka dodatków…...................................................ś........................ 189 15.4. Przykład zastosowania...................................................ś....................................... 192 15.5. Może jeszcze coś… ...................................................ś........................................... 196 15.6. Do przemyślenia...................................................ś................................................ 198 Rozdział 16. Szablony jako interfejsy ...................................................w.............. 199 16.1. Problem ...................................................ś...................................................ś.......... 199 16.2. Pierwszy przykład ...................................................ś............................................. 200 16.3. Separowanie iteracji ...................................................ś.......................................... 200 16.4. Iterowanie poprzez dowolne typy...................................................ś...................... 203 16.5. Dodawanie innych typów ...................................................ś.................................. 204 16.6. Uogólnianie sposobu przechowywania...................................................ś.............. 204 16.7. Dowód przydatności...................................................ś.......................................... 207 16.8. Podsumowanie...................................................ś...................................................ś 208 Rozdział 17. Szablony a algorytmy ogólne ...................................................w....... 211 17.1. Konkretny przykład ...................................................ś........................................... 212 17.2. Uogólnianie typu elementu...................................................ś................................ 213 17.3. Przełożenie zliczania elementów na później...................................................ś...... 214 17.4. Niezależność od adresu ...................................................ś..................................... 215 17.5. Wyszukiwanie w strukturach niebędących tablicami ........................................... 217 17.6. Podsumowanie...................................................ś...................................................ś 218 Rozdział 18. Iteratory ogólne ...................................................w.......................... 221 18.1. Inny algorytm ...................................................ś...................................................ś. 221 18.2. Kategorie i wymogi ...................................................ś........................................... 223 18.3. Iteratory wejściowe ...................................................ś........................................... 224 18.4. Iteratory wyjściowe ...................................................ś........................................... 224 18.5. Iteratory postępowe ...................................................ś........................................... 225 18.6. Iteratory dwukierunkowe...................................................ś................................... 226 18.7. Iteratory o dostępie swobodnym...................................................ś........................ 226 18.8. Dziedziczenie?...................................................ś...................................................ś 227 18.9. Wydajność...................................................ś...................................................ś...... 228 18.10. Podsumowanie ...................................................ś.................................................. 228 Rozdział 19. Korzystanie z iteratorów ogólnych .................................................. 231 19.1. Typy iteratorów ...................................................ś................................................. 232 19.2. Wirtualne sekwencje ...................................................ś......................................... 232 8 Język C++. Koncepcje i techniki programowania 19.3. Iterator strumienia wyjściowego...................................................ś........................ 234 19.4. Iterator strumienia wejściowego...................................................ś........................ 236 19.5. Omówienie ...................................................ś...................................................ś..... 239 Rozdział 20. Adaptery dla iteratorów...................................................w............... 241 20.1. Przykład...................................................ś...................................................ś.......... 241 20.2. Asymetria kierunkowa...................................................ś....................................... 243 20.3. Konsekwencja a asymetria ...................................................ś................................ 244 20.4. Automatyczne odwracanie ...................................................ś................................ 245 20.5. Omówienie ...................................................ś...................................................ś..... 247 Rozdział 21. Obiekty funkcji ...................................................w........................... 249 21.1. Przykład...................................................ś...................................................ś.......... 249 21.2. Wskaźniki funkcji...................................................ś.............................................. 252 21.3. Obiekty funkcji...................................................ś.................................................. 254 21.4. Szablony obiektów funkcji ...................................................ś................................ 255 21.5. Ukrywanie typów pośrednich...................................................ś............................ 256 21.6. Jeden typ zawiera kilka...................................................ś...................................... 257 21.7. Implementacja ...................................................ś...................................................ś 258 21.8. Omówienie ...................................................ś...................................................ś..... 260 Rozdział 22. Adaptery funkcji ...................................................w......................... 261 22.1. Dlaczego obiekty funkcji? ...................................................ś................................. 261 22.2. Obiekty funkcji dla operatorów wbudowanych ...................................................ś. 262 22.3. Funkcje wiążące ...................................................ś................................................ 263 22.4. Spojrzenie z bliska...................................................ś............................................. 264 22.5. Dziedziczenie interfejsu ...................................................ś.................................... 265 22.6. Używanie klas ...................................................ś...................................................ś 266 22.7. Omówienie ...................................................ś...................................................ś..... 267 Część IV Biblioteki ...................................................t..................269 Rozdział 23. Biblioteki w bieżącym zastosowaniu ............................................... 271 23.1. Problem ...................................................ś...................................................ś.......... 271 23.2. Istota problemu — część 1. ...................................................ś.............................. 273 23.3. Implementacja — część 1. ...................................................ś................................ 273 23.4. Istota problemu — część 2. ...................................................ś.............................. 276 23.5. Implementacja — część 2. ...................................................ś................................ 276 23.6. Omówienie ...................................................ś...................................................ś..... 278 Rozdział 24. Obiektowa lekcja projektowania interfejsu biblioteki....................... 281 24.1. Komplikacje ...................................................ś...................................................ś... 282 24.2. Poprawianie interfejsu ...................................................ś....................................... 283 24.3. Szczegółowe rozważania...................................................ś................................... 285 24.4. Pisanie kodu ...................................................ś...................................................ś... 286 24.5. Wnioski ...................................................ś...................................................ś.......... 288 Rozdział 25. Projektowanie bibliotek jako budowanie języka............................... 289 25.1. Ciągi znakowe ...................................................ś...................................................ś 289 25.2. Wyczerpanie dostępnej pamięci ...................................................ś........................ 290 25.3. Kopiowanie ...................................................ś...................................................ś.... 293 25.4. Ukrywanie implementacji...................................................ś.................................. 296 25.5. Konstruktor domyślny ...................................................ś....................................... 298 25.6. Inne operacje ...................................................ś...................................................ś.. 299 25.7. Podciągi...................................................ś...................................................ś.......... 301 25.8. Wnioski ...................................................ś...................................................ś.......... 302 Spis treści 9 Rozdział 26. Projektowanie języka jako budowanie bibliotek............................... 303 26.1. Abstrakcyjne typy danych ...................................................ś................................. 303 26.2. Biblioteki i abstrakcyjne typy danych...................................................ś................ 305 26.3. Rezerwacja pamięci...................................................ś........................................... 308 26.4. Przyporządkowywanie i inicjalizacja składowych klas ........................................ 309 26.5. Obsługa wyjątków ...................................................ś............................................. 311 26.6. Podsumowanie...................................................ś...................................................ś 312 Część V Techniki...................................................t....................313 Rozdział 27. Klasy, które się śledzą ...................................................w................ 315 27.1. Projektowanie klasy śledzącej ...................................................ś........................... 315 27.2. Tworzenie martwego kodu ...................................................ś................................ 318 27.3. Generowanie wyników inspekcji dla obiektów ...................................................ś. 319 27.4. Weryfikowanie zachowania zasobnika...................................................ś.............. 321 27.5. Podsumowanie...................................................ś...................................................ś 325 Rozdział 28. Grupowy przydział pamięci dla obiektów ......................................... 327 28.1. Problem ...................................................ś...................................................ś.......... 327 28.2. Projektowanie rozwiązania...................................................ś................................ 327 28.3. Implementacja ...................................................ś...................................................ś 330 28.4. Dziedziczenie ...................................................ś...................................................ś. 332 28.5. Podsumowanie...................................................ś...................................................ś 333 Rozdział 29. Aplikatory, manipulatory i obiekty funkcji ....................................... 335 29.1. Problem ...................................................ś...................................................ś.......... 336 29.2. Rozwiązanie ...................................................ś...................................................ś... 338 29.3. Inne rozwiązanie...................................................ś................................................ 338 29.4. Dodatkowe argumenty...................................................ś....................................... 340 29.5. Przykład...................................................ś...................................................ś.......... 341 29.6. Formy skrócone...................................................ś................................................. 343 29.7. Przemyślenia ...................................................ś...................................................ś.. 344 29.8. Uwagi historyczne, źródła i podziękowania ...................................................ś...... 345 Rozdział 30. Uniezależnianie bibliotek aplikacji od wejść i wyjść......................... 347 30.1. Problem ...................................................ś...................................................ś.......... 347 30.2. Rozwiązanie 1. — spryt i metoda siłowa...................................................ś........... 348 30.3. Rozwiązanie 2. — abstrakcyjne wyjście ...................................................ś........... 349 30.4. Rozwiązanie 3. — spryt bez metody siłowej...................................................ś..... 351 30.5. Uwagi ...................................................ś...................................................ś............. 354 Część VI Podsumowanie ...................................................t..........355 Rozdział 31. Przez złożoność do prostoty...................................................w......... 357 31.1. Świat jest złożony...................................................ś.............................................. 357 31.2. Złożoność staje się ukryta...................................................ś.................................. 358 31.3. Komputery mają to samo...................................................ś................................... 359 31.4. Komputery rozwiązują prawdziwe problemy ...................................................ś.... 361 31.5. Biblioteki klas i semantyka języka ...................................................ś.................... 362 31.6. Ułatwianie jest trudne...................................................ś........................................ 364 31.7. Abstrakcja a interfejs...................................................ś......................................... 365 31.8. Konserwacja złożoności ...................................................ś.................................... 366 10 Język C++. Koncepcje i techniki programowania Rozdział 32. „Witaj świecie” i co dalej?...................................................w.......... 367 32.1. Znajdź w pobliżu eksperta...................................................ś................................. 367 32.2. Wybierz narzędzie i opanuj je ...................................................ś........................... 368 32.3. Niektóre elementy C są ważne…...................................................ś....................... 368 32.4. …inne niekoniecznie...................................................ś......................................... 370 32.5. Wyznacz sobie szereg problemów do rozwiązania............................................... 371 32.6. Konkluzja ...................................................ś...................................................ś....... 374 Dodatki ...................................................t....................................377 Skorowidz...................................................w................................... 379 Rozdział 5. Klasy surogatów Jak zaprojektować zasobnik C++, który potencjalnie może zawierać obiekty różnych, ale powiązanych ze sobą typów? Już samo przechowywanie obiektów w zasobniku jest trudne, ponieważ zasobniki generalnie przechowują obiekty jednego typu. Prze- chowywanie wskaźników obiektów, mimo że pozwala na obsługę różnych typów z po- mocą dziedziczenia, wiąże się z koniecznością przydziału dodatkowej pamięci. Przyjrzymy się tutaj jednemu ze sposobów rozwiązania tego problemu, polegającemu na zdefiniowaniu obiektów zwanych surogatami, które zachowują się niemal tak, jak obiekty, które reprezentują, ale pozwalają na sprowadzenie całej hierarchii typów do jednego tylko typu. Surogaty to najprostsza postać klas uchwytów, opisanych we wstępie do tej części książki. W kolejnych rozdziałach rozwinięte zostaną przedsta- wione tu ogólnie zagadnienia. 5.1. Problem Przypuśćmy, że mamy hierarchię klas, która reprezentuje różne rodzaje środków transportu: ENCUU8GJKENG] RWDNKE XKTVWCNFQWDNGYGKIJV EQPUV XKTVWCNXQKFUVCTV   _ ENCUU4QCF8GJKENGRWDNKE8GJKENG]  _ ENCUU#WVQOQDKNGRWDNKE4QCF8GJKENG]  _ ENCUU#KTETCHVRWDNKE8GJKENG]  _ ENCUU*GNKEQRVGTRWDNKE#KTETCHV]  _ i tak dalej. Wszystkie środki transportu (8GJKENG) mają pewne wspólne właściwości, które opisują składowe klasy 8GJKENG. Jednak niektóre z nich mają właściwości, których nie posiadają inne. Na przykład, tylko samolot (#KTETCHV) może latać, a tylko helikopter (*GNKEQRVGT) może wykonywać lot wiszący. 62 Część II ♦ Klasy i dziedziczenie Załóżmy teraz, że chcemy śledzić zbiór różnego rodzaju środków transportu (8GJKENG). W praktyce zastosowalibyśmy zapewne pewien rodzaj klasy zasobnika. Jednak, dla uproszczenia przykładu, zadowolimy się tablicą. Spróbujmy więc: 8GJKENGRCTMKPIANQV=? Nie udało się. Dlaczego? Na pozór powodem jest to, że 8GJKENG jest abstrakcyjną klasą bazową — w końcu jej funkcje składowe YGKIJV i UVCTV to funkcje czysto abstrakcyjne. Poprzez dopisanie  w deklaracjach, funkcje te pozostały jawnie niezdefiniowane. Wynika z tego, że nie mogą istnieć obiekty klasy 8GJKENG, a jedynie obiekty klas potomnych klasie 8GJKENG. Jeżeli nie mogą istnieć obiekty 8GJKENG, niemożliwe jest również stworzenie tablicy takich obiektów. Istnieje też głębsza przyczyna naszego niepowodzenia, którą można odkryć zadając sobie pytanie: co stałoby się, gdyby istnienie obiektów klasy 8GJKENG było mimo wszys- tko możliwe. Powiedzmy, że pozbyliśmy się wszystkich czysto wirtualnych funkcji z klasy 8GJKENG i napisaliśmy: #WVQOQDKNGZ   RCTMKPIANQV=PWOAXGJKENGU ?Z Przyporządkowanie Z elementowi tablicy RCTMKPIANQV spowoduje konwersję Z na typ 8GJKENG drogą odrzucenia wszystkich składowych, które nie stanowią części samej klasy 8GJKENG. Dopiero potem operacja przyporządkowania skopiuje ten (okrojony) obiekt do tablicy RCTMKPIANQV. W efekcie zdefiniowaliśmy RCTMKPIANQV jako zbiór obiektów 8GJKENG, a nie zbiór obiek- tów klas potomnych klasie 8GJKENG. 5.2. Rozwiązanie klasyczne Normalnym sposobem na osiągnięcie elastyczności w tego typu sytuacjach jest wpro- wadzenie pośredniości. Najprostsza, możliwa tu do zastosowania forma pośredniości sprowadza się do przechowywania wskaźników, zamiast samych obiektów: 8GJKENG RCTMKPIANQV=?// tablica wskaźników Potem możemy napisać: #WVQOQDKNGZ   RCTMKPIANQV=PWOAXGJKENGU ?Z Tym sposobem pozbywamy się bezpośredniego problemu, ale pojawiają się dwa inne. Po pierwsze, to co zachowaliśmy w RCTMKPIANQV, to wskaźnik do Z, który w tym przy- kładzie jest zmienną lokalną. Wobec tego, gdy tylko zmienna Z przestanie być widoczna (dostępna), RCTMKPIANQV przestanie cokolwiek wskazywać. Rozdział 5. ♦ Klasy surogatów 63 Nowo powstały problem można by rozwiązać, przechowując w RCTMKPIANQV wskaź- niki nie do oryginalnych obiektów, ale do ich kopii. Wówczas wypadałoby również przyjąć konwencję, że uwalniając RCTMKPIANQV uwalniamy również obiekty, na które tablica ta wskazuje. Poprzedni przykład przybiera więc następującą postać: #WVQOQDKNGZ   RCTMKPIANQV=PWOAXGJKENGU ?PGY#WVQOQDKNG Z  Co prawda w efekcie takiej zmiany tablica nie przechowuje już wskaźników do lokal- nych obiektów, ale w zamian spływa na nas ciężar dynamicznego zarządzania pamię- cią. Co więcej, technika ta działa tylko wtedy, gdy znany jest statyczny typ obiektów, jakie mają być umieszczone w RCTMKPIANQV. A co, jeżeli nie znamy tych typów? Po- wiedzmy na przykład, że chcemy sprawić, by element RCTMKPIANQV=R? wskazywał na nowo utworzony RCTMKPIANQV=S?? Nie możemy napisać: KH RS ] FGNGVGRCTMKPIANQV=R? RCTMKPIANQV=R?RCTMKPIANQV=S? _ ponieważ elementy RCTMKPIANQV=R?i RCTMKPIANQV=S? wskazywały by wówczas ten sam obiekt. Nie możemy też napisać: KH RS ] FGNGVGRCTMKPIANQV=R? RCTMKPIANQV=R?PGY8GJKENG RCTMKPIANQV=S?  _ ponieważ ponownie stanęlibyśmy przed obliczem wcześniejszego problemu — obiekty typu 8GJKENG przecież nie mogą istnieć, a nawet gdyby mogły, to są niepożądane! 5.3. Wirtualne funkcje kopiujące Spróbujmy znaleźć sposób na tworzenie kopii obiektów, których typ nie jest znany w chwili kompilacji. Wiadomo, że aby zrobić cokolwiek z obiektami nieokreślonego typu w C++ należy posłużyć się funkcją wirtualną. Narzucająca się nazwa dla takiej funkcji to EQR[ lub ENQPG. Jako że najprowdopodobniej zależy nam na możliwości kopiowania dowolnego typu obiektów 8GJKENG, powinniśmy rozbudować klasę 8GJKENG o stosowną, czysto wirtu- alną funkcję: ENCUU8GJKENG] RWDNKE XKTVWCNFQWDNGYGKIJV EQPUV XKTVWCNXQKFUVCTV  XKTVWCN8GJKENG EQR[ EQPUV  _ Następnie zdefiniujemy kopię funkcji składowej w każdej klasie potomnej 8GJKENG. Idea polega na tym, że jeżeli XR wskazuje na obiekt pewnej nieustalonej klasy, potomnej 64 Część II ♦ Klasy i dziedziczenie wobec klasy 8GJKENG, to XR EQR[ da wskaźnik do nowo utworzonej kopii obiektu. Jeżeli, na przykład, klasa 6TWEM jest potomkiem (bezpośrednim lub pośrednim) klasy 8GJKENG, to jej funkcja EQR[ wygląda tak: 8GJKENG 6TWEMEQR[ EQPUV ] TGVWTPPGY6TWEM VJKU_ _ Oczywiście kiedy obiekt przestaje być potrzebny, będziemy chcieli się go pozbyć. Trzeba więc dopisać do klasy 8GJKENG wirtualny destruktor: ENCUU8GJKENG] RWDNKE XKTVWCNFQWDNGYGKIJV EQPUV XKTVWCNXQKFUVCTV  XKTVWCN8GJKENG EQR[ EQPUV XKTVWCN`8GJKENG ]_  _ 5.4. Definiowanie klasy surogatu Wiemy już, w jaki sposób można dowolnie kopiować obiekty. Zajmijmy się teraz przy- działem pamięci. Czy można w jakiś sposób uniknąć konieczności jawnego zajmowa- nia się przydziałem pamięci, zachowując jednocześnie możliwości klasy 8GJKENG w za- kresie tworzenia dynamicznych powiązań? W C++ często okazuje się, że kluczem do rozwiązania jest zastosowanie klas do repre- zentowania pojęć. Często korci mnie, by właśnie to spostrzeżenie uznać za fundamen- talną zasadę projektowania programów w C++. W kontekście kopiowania obiektów, zastosowanie tej reguły oznacza zdefiniowanie czegoś, co zachowuje się jak obiekt 8GJKENG, ale potencjalnie reprezentuje obiekt każ- dej klasy potomnej wobec klasy 8GJKENG. Obiekt takiej klasy można właśnie nazwać surogatem. Każdy surogat klasy 8GJKENG będzie reprezentował obiekt jakiejś klasy, potomnej wo- bec klasy 8GJKENG. Obiekt ten będzie istniał tak długo, jak długo surogat pozostanie z nim skojarzony. Dlatego skopiowanie surogratu spowoduje skopiowanie odpowiada- jącego mu obiektu, a przypisanie surogatowi nowej wartości będzie polegać na usu- nięciu starego obiektu, przed skopiowaniem na jego miejsce nowego.1 Na szczęście wyposażyliśmy już klasę 8GJKENG w wirtualną funkcję EQR[, która pozwala na tworze- nie takich kopii. Wobec tego surogat można zdefiniować następująco: e 1 Jak zauważył Dag Bruck, zachowanie to subtelnie różni się od zwykle spodziewanego zachowania operatora przyporządkowania, ponieważ zmienia typ obiektu, z którym skojarzony jest surogat występujący po lewej stronie operatora. Rozdział 5. ♦ Klasy surogatów 65 ENCUU8GJKENG5WTTQICVG] RWDNKE 8GJKENG5WTTQICVG  8GJKENG5WTTQICVG EQPUV8GJKENG  `8GJKENG5WTTQICVG  8GJKENG5WTTQICVG EQPUV8GJKENG5WTTQICVG  8GJKENG5WTTQICVGQRGTCVQT EQPUV8GJKENG5WTTQICVG  RTKXCVG 8GJKENG XR _ Surogat ma konstruktor, który pobiera argument const8GJKENG, co umożliwia tworze- nie surogratu każdego obiektu klasy potomnej wobec klasy 8GJKENG. Klasa posiada rów- nież konstruktor domyślny, który umożliwia tworzenie tablic obiektów 8GJKENG5WTTQICVG. Konstruktor domyślny stwarza jednak pewien problem. Skoro 8GJKENG to abstrakcyjna klasa bazowa, to jakie domyślne zachowanie powinniśmy zdefiniować dla 8GJKENG 5WTTQICVG? Jaki jest typ obiektu, na który wskazuje? Nie może to być typ 8GJKENG, bo nie mogą istnieć obiekty 8GJKENG. Dla lepszego zrozumienia, wprowadzimy pojęcie surogatu pustego, który zachowuje się podobnie jak wskaźnik zerowy. Możliwe będzie tworzenie, likwidacja i kopiowa- nie takich surogatów, ale każda inna operacja będzie traktowana jako błąd. Jak dotąd, nie mamy jeszcze innych operacji — brak ten ułatwia uzupełnienie defini- cji funkcji składowych: 8GJKENG5WTTQICVG8GJKENG5WTTQICVG XR  ]_ 8GJKENG5WTTQICVG8GJKENG5WTTQICVG EQPUV8GJKENGX XR XEQR[ ]_ 8GJKENG5WTTQICVG`8GJKENG5WTTQICVG ] FGNGVGXR _ 8GJKENG5WTTQICVG8GJKENG5WTTQICVG EQPUV8GJKENG5WTTQICVGX XR XXR!XXR EQR[  ]_ 8GJKENG5WTTQICVG 8GJKENG5WTTQICVGQRGTCVQT EQPUV8GJKENG5WTTQICVGX ] KH VJKUX ] FGNGVGXR XR XXR!XXR EQR[   _ TGVWTP VJKU _ Zastosowano tu trzy triki, które warto zapamiętać. Po pierwsze, jak widać, każde wywołanie EQR[ jest wywołaniem wirtualnym. Wywo- łania te nie mogą być inne, ponieważ obiekty klasy 8GJKENG nie istnieją. Nawet wywo- łanie XEQR[ w konstruktorze, które pobiera const8GJKENG jest wirtualne, ponieważ 8to wskaźnik, a nie sam obiekt. 66 Część II ♦ Klasy i dziedziczenie Po drugie, w konstruktorze kopii i operatorze przyporządkowania występuje test, sprawdzający, czy XXR jest niezerowe. Jest to konieczne, ponieważ w innym wypad- ku wywołanie XXR EQR[ zakończyłoby się błędem. Po trzecie, w operatorze przyporządkowania następuje sprawdzenie, czy surogat nie jest przyporządkowywany sobie samemu. Aby zakończyć tworzenie klasy surogatu, wystarczy jeszcze uzupełnić ją o obsługę innych operacji obsługiwanych przez klasę 8GJKENG. We wcześniejszym przykładzie były to funkcje YGKIJV i UVCTV, dodajmy je więc do klasy 8GJKENG5WTTQICVG: ENCUU8GJKENG5WTTQICVG] RWDNKE 8GJKENG5WTTQICVG  8GJKENG5WTTQICVG EQPUV8GJKENG  `8GJKENG5WTTQICVG  8GJKENG5WTTQICVG EQPUV8GJKENG5WTTQICVG  8GJKENG5WTTQICVGQRGTCVQT EQPUV8GJKENG5WTTQICVG  // operacje z klasy 8GJKENG FQWDNGYGKIJV EQPUV XQKFUVCTV   RTKXCVG 8GJKENG XR _ Jak widać, dodane funkcje nie są wirtualne — jedyne obiekty, jakich tutaj używamy, są klasy 8GJKENG5WTTQICVG. Nie ma tu obiektów jakiejkolwiek klasy potomnej 8GJKENG 5WTTQICVG. Oczywiście same funkcje wywołują wirtualne funkcje w odpowiadającym im obiekcie 8GJKENG. Funkcje te również powinny sprawdzać, czy XR jest niezerowe: FQWDNG8GJKENG5WTTQICVGYGKIJV EQPUV ] KH XR VJTQYGORV[8GJKENG5WTTQICVGYGKIJV  TGVWTPXR YGKIJV  _ XQKF8GJKENG5WTTQICVGUVCTV ] KH XR VJTQYGORV[8GJKENG5WTTQICVGUVCTV  XR UVCTV  _ Po wykonaniu całej tej pracy, zdefiniowanie parkingu (RCTMKPIANQV) jest już proste: 8GJKENG5WTTQICVGRCTMKPIANQV=? #WVQOQDKNGZ RCTMKPIANQV=PWOAXGJKENGU ?Z Ostatnia instrukcja jest tożsama: RCTMKPIANQV=PWOAXGJKENGU ?8GJKENG5WTTQICVG Z  co powoduje stworzenie kopii obiektu :, wiąże obiekt 8GJKENG5WTTQICVG z tą kopią, a następnie przyporządkowuje ten obiekt do elementu tablicy RCTMKPIANQV. Z chwilą usunięcia tablicy RCTMKPIANQV wszystkie te kopie również zostaną usunięte. Rozdział 5. ♦ Klasy surogatów 67 5.5. Podsumowanie Połączenie dziedziczenia z zasobnikami zmusza do zajęcia się dwoma kwestiami: kontrolowaniem przydziału pamięci oraz umieszczaniem obiektów różnych typów w jednym zasobniku. Obydwie te kwestie można rozwiązać posługując się fundamen- talną techniką w C++ polegającą na reprezentowaniu pojęć za pomocą klas. W ten spo- sób otrzymamy pojedynczą klasę zwaną surogatem, której każdy obiekt reprezentuje je- den inny obiekt o klasie dowolnej spośród całej hierarchii. Problem rozwiązujemy umieszczając w miejsce obiektów w naszym zasobniku reprezentujące je surogaty.
Pobierz darmowy fragment (pdf)

Gdzie kupić całą publikację:

Język C++. Koncepcje i techniki programowania
Autor:
,

Opinie na temat publikacji:


Inne popularne pozycje z tej kategorii:


Czytaj również:


Prowadzisz stronę lub blog? Wstaw link do fragmentu tej książki i współpracuj z Cyfroteką: