Cyfroteka.pl

klikaj i czytaj online

Cyfro
Czytomierz
00364 010304 11037719 na godz. na dobę w sumie
Thinking in C++. Edycja polska. Tom 2 - książka
Thinking in C++. Edycja polska. Tom 2 - książka
Autor: , Liczba stron: 688
Wydawca: Helion Język publikacji: polski
ISBN: 83-7361-409-5 Data wydania:
Lektor:
Kategoria: ebooki >> komputery i informatyka >> programowanie >> c++ - programowanie
Porównaj ceny (książka, ebook, audiobook).

Szkoła programowania Bruce'a Eckela!

Podczas nauki tworzenia aplikacji w języku C++ towarzyszyć Ci będzie jeden z najlepszych dydaktyków programowania na świecie!

Nauka języka C++ i szczegółowe poznanie jego możliwości to poważne wyzwanie nie tylko dla początkującego, ale również dla zaawansowanego programisty. W książce 'Thinking in C++. Edycja polska' Bruce Eckel w doskonały sposób przedstawił podstawowe zagadnienia związane z tym językiem. Jeśli opanowałeś materiał z tej książki, możesz rozpocząć lekturę drugiego tomu.

Następnym krokiem jest -- 'Thinking in C++. Edycja polska. Tom II' -- kolejny bestseller Bruce'a Eckela poświęcony językowi C++. Tym razem Bruce w typowy dla siebie, prosty i zrozumiały sposób opisuje zaawansowane aspekty programowania w C++. Dowiesz się, jak korzystać z referencji, przeciążania operatorów, dziedziczenia i obiektów dynamicznych, a także poznasz zagadnienia zaawansowane -- prawidłowe użycie szablonów, wyjątków i wielokrotnego dziedziczenia. Wszystkie tematy opatrzone są ćwiczeniami.

Kody źródłowe znajdujące się w książce są zgodne z wieloma kompilatorami C++.

O autorach:
Bruce Eckel jest prezesem MindView, Inc., firmy prowadzącej zarówno otwarte jak i zamknięte kursy treningowe; zajmującej się też doradztwem, nadzorem i kontrolą nad projektami związanymi z technologiami obiektowymi i wzorcami projektowymi. [więcej...\

Chuck Allison jest matematykiem, pełniącym obecnie funkcję wykładowcy na wydziale informatyki uniwersytetu stanowego Utah Valley. Do niedawna pełnił funkcję redaktora w magazynie C/C++ Users Journal. [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 Thinking in C++. Edycja polska. Tom II Autor: Bruce Eckel, Chuck Allison T³umaczenie: Przemys³aw Szeremiota, Tomasz ¯mijewski ISBN: 83-7361-409-5 Tytu³ orygina³u: Thinking in C++, Vol. 2: Practical Programming, Second Edition Format: B5, stron: 688 Nauka jêzyka C++ i szczegó³owe poznanie jego mo¿liwoġci to powa¿ne wyzwanie nie tylko dla pocz¹tkuj¹cego, ale równie¿ dla zaawansowanego programisty. W ksi¹¿ce Thinking in C++. Edycja polska. Bruce Eckel w doskona³y sposób przedstawi³ podstawowe zagadnienia zwi¹zane z tym jêzykiem. Jeġli opanowa³eġ materia³ z tej ksi¹¿ki, mo¿esz rozpocz¹æ lekturê drugiego tomu. Ksi¹¿ka, któr¹ trzymasz w rêce — Thinking in C++. Edycja polska. Tom II to kolejny bestseller Bruce’a Eckela poġwiêcony jêzykowi C++. Tym razem Bruce w typowy dla siebie, prosty i zrozumia³y sposób opisuje zaawansowane aspekty programowania w C++. Dowiesz siê, jak korzystaæ z referencji, przeci¹¿ania operatorów, dziedziczenia i obiektów dynamicznych, a tak¿e poznasz zagadnienia zaawansowane — prawid³owe u¿ycie szablonów, wyj¹tków i wielokrotnego dziedziczenia. Wszystkie tematy opatrzone s¹ æwiczeniami. • obs³uga wyj¹tków • programowanie defensywne • standardowa biblioteka C++ • strumienie wejġcia-wyjġcia • wzorce projektowe • zaawansowane metody programowania obiektowego • wspó³bie¿noġæ Kody ĥród³owe znajduj¹ce siê w ksi¹¿ce s¹ zgodne z wieloma kompilatorami C++. Bruce Eckel jest prezesem MindView, Inc., firmy prowadz¹cej kursy i szkolenia zarówno otwarte, jak i zamkniête, a tak¿e zajmuj¹cej siê doradztwem i nadzorem nad projektami zwi¹zanymi z technologiami obiektowymi i wzorcami projektowymi. Jest autorem ksi¹¿ek Thinking in Java oraz pierwszego tomu Thinking in C++, a tak¿e wspó³autorem ksi¹¿ki Thinking in C#. Napisa³ tak¿e kilka innych ksi¹¿ek i ponad 150 artyku³ów. Od ponad 20 lat prowadzi wyk³ady i seminaria na ca³ym ġwiecie. By³ cz³onkiem Komitetu Standardów C++. Zdoby³ tytu³ naukowy w dziedzinie fizyki stosowanej i in¿ynierii oprogramowania. Chuck Allison jest matematykiem, pe³ni¹cym obecnie funkcjê wyk³adowcy na wydziale informatyki uniwersytetu stanowego Utah Valley. Do niedawna pe³ni³ funkcjê redaktora w magazynie C/C++ Users Journal. Jest tak¿e autorem ksi¹¿ki C C++ Code Capsules: A Guide for Practitioners i kilkudziesiêciu artyku³ów poġwiêconych programowaniu w C i C++. Bra³ udzia³ w tworzeniu standardu C++. Jego artyku³y i omówienia napisanych przez niego ksi¹¿ek mo¿na znaleĥæ w witrynie WWW www.freshsources.com. Spis treści Wstęp ...................................................z.......................................... 11 Cele...............................................i...................................................i..................................11 Rozdziały...................................................i...................................................i.....................12 Ćwiczenia ...................................................i...................................................i....................14 Rozwiązania do ćwiczeń...................................................i..........................................14 Kod źródłowy...................................................i...................................................i..............15 Obsługiwane wersje języka...................................................i............................................16 Standardy językowe ...................................................i...................................................i....17 O okładce..........................................i...................................................i..............................17 Część I Tworzenie niezawodnych systemów.................................19 Rozdział 1. Obsługa wyjątków...................................................z......................... 21 Tradycyjna obsługa błędów ...................................................i...........................................22 Wyrzucanie wyjątku...................................................i...................................................i....24 Przechwytywanie wyjątku...................................................i..............................................25 Blok try ...................................................i...................................................i.................25 Obsługa wyjątków ...................................................i...................................................i25 Zakończenie i kontynuacja ...................................................i......................................26 Dopasowywanie wyjątków ...................................................i............................................27 Przechwytywanie dowolnych wyjątków...................................................i..................29 Ponowne wyrzucanie wyjątku ...................................................i.................................29 Wyjątki nieprzechwycone...................................................i........................................30 Czyszczenie...................................................i...................................................i.................32 Zarządzanie zasobami...................................................i..............................................33 Wszystko jest obiektem ...................................................i...........................................34 auto_ptr ...................................................i...................................................i.................36 Bloki try na poziomie funkcji ...................................................i..................................38 Wyjątki standardowe...................................................i...................................................i...39 Specyfikacje wyjątków ...................................................i..................................................41 Jakieś lepsze specyfikacje wyjątków? ...................................................i.....................45 Specyfikacja wyjątków i dziedziczenie ...................................................i...................45 Kiedy nie używać specyfikacji wyjątków?...................................................i..............46 Bezpieczeństwo wyjątków ...................................................i.............................................47 Programowanie z użyciem wyjątków ...................................................i............................50 Kiedy unikać wyjątków?...................................................i..........................................51 Typowe zastosowania wyjątków ...................................................i.............................52 Narzuty ...................................................i...................................................i........................55 Podsumowanie ...................................................i...................................................i............57 Ćwiczenia ...................................................i...................................................i....................57 6 Thinking in C++. Edycja polska. Tom 2 Rozdział 2. Programowanie defensywne ...................................................z.......... 59 Asercje...................................................i...................................................i.........................61 Najprostszy system testów jednostkowych, który ma szansę zadziałać ...........................65 Automatyczne testowanie ...................................................i........................................66 Szkielet TestSuite...................................................i...................................................i..70 Zestawy testowe...................................................i...................................................i....73 Kod szkieletu testowego ...................................................i..........................................74 Techniki usuwania błędów...................................................i.............................................79 Makra śledzące...................................................i...................................................i......79 Plik śladu............................................i...................................................i......................80 Znajdowanie wycieków pamięci...................................................i..............................81 Podsumowanie ...................................................i...................................................i............86 Ćwiczenia ...................................................i...................................................i....................86 Część II Standardowa biblioteka C++...........................................91 Rozdział 3. Wszystko o łańcuchach...................................................z................. 93 Czym jest łańcuch?...................................................i...................................................i......94 Tworzenie i inicjalizacja łańcuchów C++...................................................i........................95 Operacje na łańcuchach...................................................i..................................................98 Dodawanie, wstawianie i łączenie łańcuchów...................................................i.........98 Podmiana znaków łańcucha...................................................i...................................100 Sklejanie za pomocą przeciążonych operatorów spoza klasy...................................103 Szukanie w łańcuchach ...................................................i................................................104 Znajdowanie od końca ...................................................i...........................................107 Znajdowanie pierwszego i ostatniego ze zbioru znaków..........................................109 Usuwanie znaków z łańcuchów ...................................................i.............................111 Porównywanie łańcuchów ...................................................i.....................................112 Łańcuchy a znaki ...................................................i...................................................i116 Przykład zastosowania łańcuchów ...................................................i...............................121 Podsumowanie ...................................................i...................................................i..........125 Ćwiczenia ...................................................i...................................................i..................126 Rozdział 4. Strumienie wejścia-wyjścia...................................................z.......... 129 Po co nowa biblioteka? ...................................................i................................................129 Iostream przybywa z odsieczą...................................................i......................................133 Wstawianie i pobieranie...................................................i.........................................134 Typowe zastosowania ...................................................i............................................137 Dane wejściowe pobierane wierszami ...................................................i...................139 Obsługa błędów strumieni...................................................i............................................140 Strumienie związane z plikami ...................................................i....................................143 Przykład przetwarzania pliku...................................................i.................................143 Tryby otwarcia ...................................................i...................................................i....145 Buforowanie strumieni...................................................i.................................................146 Przeszukiwanie strumieni wejścia-wyjścia ...................................................i..................148 Strumienie powiązane z łańcuchami ...................................................i............................151 Łańcuchowe strumienie wejściowe ...................................................i.......................152 Łańcuchowe strumienie wyjściowe ...................................................i.......................153 Formatowanie strumieni wyjściowych...................................................i.........................156 Flagi formatujące ...................................................i...................................................i156 Pola formatujące ...................................................i...................................................i.158 Szerokość, wypełnienie, dokładność ...................................................i.....................159 Kompletny przykład...................................................i...............................................160 Spis treści 7 Manipulatory ...................................................i...................................................i.............162 Manipulatory z argumentami...................................................i.................................163 Tworzenie manipulatorów ...................................................i.....................................166 Efektory...................................................i...................................................i...............167 Przykłady wykorzystujące iostream...................................................i.............................169 Zarządzanie kodem źródłowym biblioteki klas ...................................................i.....169 Wykrywanie błędów kompilatora...................................................i..........................173 Prosty rejestrator danych...................................................i........................................175 Obsługa wielu języków ...................................................i................................................179 Strumienie znaków szerokich ...................................................i................................179 Ustawienia lokalne...................................................i.................................................181 Podsumowanie ...................................................i...................................................i..........183 Ćwiczenia ...................................................i...................................................i..................183 Rozdział 5. Wszystko o szablonach ...................................................z............... 187 Parametry szablonów ...................................................i...................................................i187 Parametry szablonów niebędące typami...................................................i................188 Domyślne argumenty szablonów...................................................i...........................190 Szablony jako parametry szablonów ...................................................i.....................191 Słowo kluczowe typename ...................................................i....................................196 Użycie słowa kluczowego template jako wskazówki...............................................198 Szablony składowe...................................................i.................................................199 Szablony funkcji...................................................i...................................................i........201 Dedukowanie typu argumentów szablonu funkcji...................................................i.202 Przeciążanie szablonów funkcji...................................................i.............................205 Pobieranie adresu wygenerowanej z szablonu funkcji .............................................206 Stosowanie funkcji do sekwencji STL...................................................i...................209 Częściowe uporządkowanie szablonów funkcji ...................................................i....212 Specjalizacja szablonów...................................................i...............................................213 Specjalizacja jawna...................................................i................................................214 Specjalizacja częściowa ...................................................i.........................................215 Przykład praktyczny...................................................i...............................................217 Unikanie nadmiarowego kodu ...................................................i...............................220 Odszukiwanie nazw...................................................i...................................................i...224 Nazwy w szablonach...................................................i..............................................224 Szablony i funkcje zaprzyjaźnione ...................................................i........................228 Idiomy programowania za pomocą szablonów...................................................i............233 Cechy charakterystyczne ...................................................i.......................................233 Reguły ...................................................i...................................................i.................238 Tajemniczo powtarzający się wzorzec szablonów ...................................................i240 Szablony i metaprogramowanie ...................................................i...................................242 Programowanie na poziomie kompilacji ...................................................i...............243 Szablony wyrażeń ...................................................i..................................................251 Modele kompilacji szablonów ...................................................i.....................................256 Model włączania ...................................................i...................................................i.256 Ukonkretnianie jawne ...................................................i............................................257 Model separacji...................................................i...................................................i...259 Podsumowanie ...................................................i...................................................i..........260 Ćwiczenia ...................................................i...................................................i..................261 Rozdział 6. Algorytmy uogólnione...................................................z.................. 265 Algorytmy uogólnione — wprowadzenie ...................................................i.......................265 Predykaty ...................................................i...................................................i............268 Iteratory strumieni...................................................i..................................................270 Złożoność algorytmu ...................................................i.............................................272 8 Thinking in C++. Edycja polska. Tom 2 Obiekty funkcyjne ...................................................i...................................................i.....274 Klasyfikacja obiektów funkcyjnych ...................................................i......................275 Automatyczne tworzenie obiektów funkcyjnych...................................................i...276 Adaptowalność obiektów funkcyjnych...................................................i..................279 Więcej przykładów wykorzystania obiektów funkcyjnych ......................................281 Adaptery wskaźników do funkcji ...................................................i..........................287 Pisanie własnych adapterów obiektów funkcyjnych ................................................293 Katalog algorytmów STL...................................................i.............................................297 Narzędzia przydatne w tworzeniu przykładów...................................................i......299 Wypełnianie i generowanie sekwencji...................................................i...................303 Zliczanie...................................................i...................................................i..............304 Manipulowanie sekwencjami...................................................i.................................305 Wyszukiwanie i zastępowanie elementów...................................................i.............310 Porównywanie sekwencji...................................................i.......................................316 Usuwanie elementów sekwencji ...................................................i............................319 Sortowanie i operacje na sekwencjach posortowanych ............................................322 Operacje na stertach...................................................i...............................................331 Wykonywanie operacji na wszystkich elementach sekwencji..................................332 Algorytmy numeryczne ...................................................i.........................................339 Narzędzia ...................................................i...................................................i............342 Tworzenie własnych algorytmów uogólnionych ...................................................i.........343 Podsumowanie ...................................................i...................................................i..........345 Ćwiczenia ...................................................i...................................................i..................345 Rozdział 7. Kontenery...................................................z................................... 351 Kontenery i iteratory ...................................................i...................................................i.351 Dokumentacja biblioteki STL...................................................i................................353 Wprowadzenie...................................................i...................................................i...........353 Kontenery przechowujące ciągi znakowe...................................................i..............358 Dziedziczenie po kontenerach STL ...................................................i.......................360 Kraina iteratorów...................................................i...................................................i.......362 Iterator w kontenerach dwukierunkowych...................................................i.............364 Kategorie iteratorów ...................................................i..............................................365 Iteratory predefiniowane...................................................i........................................367 Kontenery sekwencyjne: vector, list i deque...................................................i................373 Podstawowe operacje na kontenerach sekwencyjnych .................................................373 Kontener typu vector...................................................i..............................................376 Kontener typu deque ...................................................i..............................................383 Konwersja sekwencji ...................................................i.............................................385 Kontrolowany dostęp swobodny...................................................i............................387 Kontener typu list...................................................i...................................................i388 Wymienianie całych sekwencji...................................................i..............................393 Kontener typu set ...................................................i...................................................i......394 Klasa iteratora słów...................................................i................................................397 Szablon stack...................................................i...................................................i.............402 Szablon queue ...................................................i...................................................i...........405 Kolejki priorytetowe ...................................................i...................................................i.410 Przechowywanie bitów ...................................................i................................................418 Typ bitset n ...................................................i...................................................i......419 Typ vector bool ...................................................i..................................................422 Kontenery asocjacyjne ...................................................i.................................................424 Generowanie elementów i wypełnianie kontenerów asocjacyjnych ........................428 Magia kontenerów typu map ...................................................i.................................431 Kontener typu multimap ...................................................i........................................433 Kontener typu multiset...................................................i...........................................436 Spis treści 9 Korzystanie z wielu kontenerów STL...................................................i..........................439 Czyszczenie kontenera wskaźników ...................................................i............................442 Tworzenie własnych kontenerów...................................................i.................................444 Rozszerzenia biblioteki STL ...................................................i........................................446 Kontenery spoza STL...................................................i...................................................i448 Podsumowanie ...................................................i...................................................i..........452 Ćwiczenia ...................................................i...................................................i..................453 Część III Zagadnienia zaawansowane .........................................457 Rozdział 8. Rozpoznawanie typu w czasie wykonania programu......................... 459 Rzutowanie w czasie wykonania...................................................i..................................459 Operator typeid...................................................i...................................................i..........464 Rzutowanie na pośrednie poziomy hierarchii klas ...................................................i466 Wskaźniki na typ void ...................................................i...........................................467 RTTI a szablony...................................................i...................................................i..468 Wielodziedziczenie ...................................................i...................................................i...469 Zastosowania mechanizmu RTTI...................................................i.................................470 Sortownia odpadków ...................................................i.............................................471 Implementacja i narzuty mechanizmu RTTI...................................................i................475 Podsumowanie ...................................................i...................................................i..........475 Ćwiczenia ...................................................i...................................................i..................476 Rozdział 9. Wielodziedziczenie ...................................................z...................... 479 Wprowadzenie do wielodziedziczenia ...................................................i.........................479 Dziedziczenie interfejsu ...................................................i...............................................481 Dziedziczenie implementacji ...................................................i.......................................484 Duplikaty podobiektów ...................................................i................................................489 Wirtualne klasy bazowe ...................................................i...............................................493 Wyszukiwanie nazw...................................................i...................................................i..502 Unikanie wielodziedziczenia...................................................i........................................504 Rozszerzanie interfejsu ...................................................i................................................506 Podsumowanie ...................................................i...................................................i..........509 Ćwiczenia ...................................................i...................................................i..................510 Rozdział 10. Wzorce projektowe ...................................................z..................... 513 Pojęcie wzorca...................................................i...................................................i...........513 Wyższość kompozycji nad dziedziczeniem...................................................i...........515 Klasyfikacja wzorców ...................................................i..................................................515 Właściwości, pojęcia, wzorce ...................................................i................................516 Upraszczanie pojęć...................................................i...................................................i....516 Posłaniec ...................................................i...................................................i.............517 Parametr zbiorczy ...................................................i..................................................518 Singleton............................................i...................................................i...........................519 Odmiany Singletona...................................................i...............................................520 Polecenie — wybór operacji ...................................................i........................................524 Polecenia izolujące obsługę zdarzeń...................................................i......................526 Izolowanie obiektów ...................................................i...................................................i.529 Pośrednik — dostęp do innego obiektu ...................................................i.................529 Stan — modyfikowanie czynności obiektu ...................................................i...........531 Adapter ...................................................i...................................................i......................532 Metoda szablonowa...................................................i...................................................i...535 Strategia — dynamiczny wybór algorytmu ...................................................i.................536 Łańcuch odpowiedzialności — wypróbowywanie sekwencji strategii ................................537 10 Thinking in C++. Edycja polska. Tom 2 Fabryki — hermetyzacja procesu tworzenia obiektu...................................................i...540 Fabryki polimorficzne...................................................i............................................542 Fabryka abstrakcyjna ...................................................i.............................................545 Konstruktory wirtualne ...................................................i..........................................547 Builder — tworzenie złożonych obiektów ...................................................i......................552 Obserwator ...................................................i...................................................i................558 Pojęcie klasy wewnętrznej...................................................i.....................................561 Przykład zastosowania Obserwatora...................................................i......................564 Dyspozycja wielokrotna...................................................i...............................................567 Wielokrotna dyspozycja z wzorcem Wizytator ...................................................i.....571 Podsumowanie ...................................................i...................................................i..........575 Ćwiczenia ...................................................i...................................................i..................575 Rozdział 11. Współbieżność...................................................z............................ 579 Motywacja...................................................i...................................................i.................580 Współbieżność w języku C++...................................................i......................................582 Instalacja biblioteki ZThread ...................................................i.................................582 Definiowanie zadań...................................................i...................................................i...584 Klasa Thread ...................................................i...................................................i.............585 Tworzenie interfejsu użytkownika o krótkim czasie odpowiedzi.............................587 Uproszczenie kodu z wykorzystaniem Wykonawców .............................................589 Tymczasowe zawieszanie działania wątków ...................................................i.........592 Usypianie wątków...................................................i..................................................594 Priorytety wątków...................................................i..................................................595 Współdzielenie ograniczonych zasobów...................................................i.........................597 Gwarantowanie istnienia obiektów...................................................i........................597 Niewłaściwe odwołania do zasobów ...................................................i.....................601 Kontrola dostępu...................................................i...................................................i.603 Uproszczenie kodu z wykorzystaniem Strażników ..................................................605 Pamięć lokalna wątku ...................................................i............................................608 Zatrzymywanie zadań ...................................................i..................................................610 Zapobieganie kolizji odwołań do strumieni wejścia-wyjścia ...................................610 Ogród botaniczny...................................................i...................................................i611 Zatrzymywanie zadań zablokowanych ...................................................i..................616 Przerwanie...................................................i...................................................i...........617 Współpraca wątków ...................................................i...................................................i..623 Oczekiwanie i nadawanie sygnałów ...................................................i......................623 Zależności typu producent-konsument ...................................................i..................627 Rozwiązywanie problemów wielowątkowości przez kolejkowanie.........................630 Sygnalizacja rozgłoszeniowa ...................................................i.................................635 Zakleszczenie ...................................................i...................................................i............641 Podsumowanie ...................................................i...................................................i..........647 Ćwiczenia ...................................................i...................................................i..................649 Dodatki ...................................................o....................................653 Dodatek A Zalecana lektura ...................................................z........................ 655 Język C++...................................................i...................................................i..................655 Książki Bruce’a Eckela...................................................i..........................................656 Książki Chucka Allisona...................................................i........................................657 Zaawansowane omówienia języka C++...................................................i.......................658 Książki o wzorcach projektowych ...................................................i...............................660 Dodatek B Uzupełnienie ...................................................z............................... 661 Skorowidz...................................................z................................... 667 Rozdział 5. Wszystko o szablonach Szablony C++ to zdecydowanie więcej niż „kontenery zmiennych typu T”. Wpraw- dzie początkowo chodziło o stworzenie bezpiecznych ze względu na typy, ogólnych kontenerów, ale we współczesnym C++ szablony służą też do generowania specjali- zowanego kodu i optymalizowania wykonania programu już na etapie kompilacji po- przez użycie specyficznych konstrukcji programistycznyCch. W niniejszym rozdziale Czytelnik będzie mógł się praktycznie zapoznać z możliwo- ściami (i pułapkami) programowania za pomocą szablonów C++. Obszerniejszą analizę odpowiednich zagadnień języka oraz pułapek znaleźć można w doskonałej książce Davida Vandevoorde’a i Nico Josuttisa1. Parametry szablonów Jak już powiedzieliśmy w pierwszym tomie, szablony mają dwie odmiany i występują jako: szablony funkcji i szablony klas. Jedne i drugie są w całości opisane swoimi pa- rametrami. Każdy parametr szablonu sam może być: 1. 2. Typem (wbudowanym lub zdefiniowanym przez użytkownika). Stałą w chwili kompilacji (na przykład liczby całkowitye, wskaźniki i referencje danych statycznych; często określa się takie stałe jayko parametry niebędące typami). 3. Innym szablonem. Wszystkie przykłady z pierwszego tomu należą do pierwszej kategorii i takie parametry występują najczęściej. Klasycznym przykładem prostego szablonu będącego kontenerem jest klasa Stack (Stos). Jako kontener obiekt Stack nie dba o to, jakiego typu obiekty zawiera; sposób przechowywania tych obiektów nie zmienia się zależnie od ich typu. Z tego powodu można użyć parametru będącego typem do opisania typu obiektów prze- chowywanych na stosie: 1 Vandevoorde i Josuttis, C++. Szablony. Vademecum profesjonalisty, Helion, 2003. 188 Część II ♦ Standardowa biblioteka C++ VGORNCVGENCUU6 ENCUU5VCEM] 6 FCVC UK\GAVEQWPV RWDNKE XQKFRWUJ EQPUV6V  KVF _ Konkretny typ, który w danym stosie ma być użyty, podaje się jako argument odpo- wiadający parametrowi T: 5VCEMKPV O[5VCEMUVQUNKE\DECđMQYKV[EJKPV Kompilator używa obiektu Stack dostosowanego do typu int przez podstawienie int pod T i wygenerowanie odpowiedniego kodu. Nazwa instancji klasy wygenerowanej na podstawie tego szablonu to Stack int . Parametry szablonów niebędące typami Można też używać parametrów szablonów niebędących typami, o ile tylko odpowiadają one liczbom całkowitym znanym na etapie kompilacji. Można, na przykład, stworzyć stos o ustalonej wielkości, przekazując parametr niebędący typem, odpowiadający wielkości tablicy użytej do implementacji tego stosu: VGORNCVGENCUU6UK\GAV0 ENCUU5VCEM] 6FCVC=0?0VQWUVCNQPCRQLGOPQħè UK\GAVEQWPV RWDNKE XQKFRWUJ EQPUV6V  KVF _ Podczas tworzenia instancji takiego szablonu musisz podać wartość stałą znaną pod- czas kompilacji, która będzie użyta jako wartość paryametru N: 5VCEMKPV O[(KZGF5VCEM Wartość N jest znana już na etapie kompilacji, więc tablica data może zostać umiesz- czona na stosie, a nie w pamięci wymagającej alokowania, co może przyspieszyć działanie programu dzięki uniknięciu opóźnień związanych z dynamiczną alokacją pamięci. Zgodnie z przedstawioną wcześniej zasadą, nazwą uzyskanej w ten sposób klasy będzie Stack int, 100 . Oznacza to, że każda kolejna wartość N powoduje utworzenie innego typu klasy. Na przykład klasa Stack int, 99 to klasa inna niż Stack int, 100 . Szablon klasy bitset, szczegółowo omawiany w rozdziale 7., to jedyna klasa standar- dowej biblioteki C++, w której używany jest parametr szablonu niebędący typem; pa- rametr ten określa liczbę bitów, jakie może przechowywać obiekt bitset. Poniższy przykładowy generator liczb losowych używa obiektu bitset do śledzenia liczb tak, aby wszystkie liczby w danym zakresie były zwracane w losowej kolejności bez po- wtórzeń tak długo, aż użyte zostaną wszystkie liczby. Poniższy przykład pokazuje także przeciążenie funkcji operator() w celu uzyskania składni podobnej do wywoła- nia funkcji: Rozdział 5. ♦ Wszystko o szablonach 189  7TCPFJ ]DQT_ .QUQYGIGPGTQYCPKGNKE\DDG\RQYVÎT\Gē KHPFGH74#0 A* FGHKPG74#0 A* KPENWFGDKVUGV KPENWFGEUVFFGH KPENWFGEUVFNKD KPENWFGEVKOG WUKPIUVFUK\GAV WUKPIUVFDKVUGV VGORNCVGUK\GAV7RRGT$QWPF ENCUU7TCPF] DKVUGV7RRGT$QWPF WUGF RWDNKE 7TCPF ] UTCPF VKOG  .QUQYQ _ UK\GAVQRGTCVQT (WPMELCIGPGTCVQT _ VGORNCVGUK\GAV7RRGT$QWPF KPNKPGUK\GAV7TCPF7RRGT$QWPF QRGTCVQT ] KH WUGFEQWPV 7RRGT$QWPF WUGFTGUGV KQFPQYC Y[E\[ħèDKVUGV UK\GAVPGYXCN YJKNG WUGF=PGYXCNTCPF 7RRGT$QWPF? CľFQ\PCNG\KGPKCPKGRQYVCT\CNPGLYCTVQħEK WUGF=PGYXCN?VTWG TGVWTPPGYXCN _ GPFKH74#0 A*` Niepowtarzalność w klasie Urand uzyskujemy dzięki śledzeniu w zbiorze bitset wszystkich liczb, jakie występują w zakresie (górne ograniczenie tego zakresu poda- wane jest jako argument szablonu) i rejestrując użycie każdej liczby przez ustawienie odpowiedniego bitu w strukturze used. Kiedy wszystkie liczby zostaną użyte, zbiór bitset jest czyszczony i losowanie odbywa się od nowa. Oto prosty przykład użycia obiektu Urand:  7TCPF6GUVERR ]DQT_ KPENWFGKQUVTGCO KPENWFG7TCPFJ WUKPIPCOGURCEGUVF KPVOCKP ] 7TCPF W HQT KPVKK K EQWVW    _` Jak jeszcze powiemy dalej, argumenty szablonów niebędące typami są ważne w przypadku optymalizowania obliczeń numerycznych. 190 Część II ♦ Standardowa biblioteka C++ Domyślne argumenty szablonów Parametrom szablonu klasy można przypisać argumenty domyślne (niedopuszczalne jest ich stosowanie w przypadku szablonów funkcji). Tak jak w przypadku argumen- tów domyślnych funkcji powinno się je definiować tylko raz, w pierwszej deklaracji lub definicji widzianej przez kompilator. Kiedy jakiś argument domyślny zostanie już zdefiniowany, wszystkie dalsze szablony też muszą mieć wartości domyślne. Aby pokazana powyżej klasa stosu o ustalonej wielkości była łatwiejsza w użyciu, można dodać do niej argument domyślny: VGORNCVGENCUU6UK\GAV0 ENCUU5VCEM] 6FCVC=0?0VQWUVCNQPCRQLGOPQħè UK\GAVEQWPV RWDNKE XQKFRWUJ EQPUV6V  KVF _ Teraz, jeśli podczas deklarowania obiektu Stack pominięty zostanie drugi argument szablonu, wartość N domyślnie będzie równa 100. Można też podać wartości domyślne dla wszystkich argumentów, ale wtedy i tak podczas deklarowania instancji szablonu trzeba będzie użyć pustej pary nawiasów, aby kompilator „wiedział”, że chodzi o szablon klasy: VGORNCVGENCUU6KPVUK\GAV0 QDCCTIWOGPV[FQO[ħNPG ENCUU5VCEM] 6FCVC=0?0VQWUVCNQPCRQLGOPQħè UK\GAVEQWPV RWDNKE XQKFRWUJ EQPUV6V  KVF _ 5VCEM O[5VCEMTÎYPQYCľPG5VCEMKPV Argumenty domyślne są intensywnie wykorzystywane w standardowej bibliotece C++. Przykładowo szablon klasy vector zadeklarowany został następująco: VGORNCVGENCUU6ENCUU#NNQECVQTCNNQECVQT6  ENCUUXGEVQT Zwróć uwagę na spację między dwoma zamykającymi nawiasami kątowymi. Dzięki niej kompilator nie zinterpretuje tych dwóch znaków ( ) jako operatora przesunięcia w prawo. Z powyższej deklaracji wynika, że szablon vector tak naprawdę ma dwa argumenty: typ przechowywanych obiektów oraz typ odpowiadający alokatorowi używanemu w wektorze (więcej o alokatorach powiemy w rozdziale 7.) Jeśli drugi argument zostanie pominięty, użyty zostanie standardowy szablon allocator sparametryzowany pierwszym parametrem szablonu. Z deklaracji wynika też, że w kolejnych parametrach szablonów można używać parametrów poprzednich — tutaj tak użyto parametru T. Rozdział 5. ♦ Wszystko o szablonach 191 Wprawdzie w szablonach funkcji nie można używać domyślnych argumentów sza- blonu, ale parametrów szablonów można używać jako argumentów domyślnych zwy- kłych funkcji. Poniższy szablon funkcji sumuje elementy syekwencji:  (WPE GHERR KPENWFGKQUVTGCO WUKPIPCOGURCEGUVF VGORNCVGENCUU6 6UWO 6 D6 G6KPKV6 ] YJKNG DG KPKV  D  TGVWTPKPKV _ KPVOCKP ] KPVC=?]_ EQWVUWO CC UK\GQHCUK\GQHC=? GPFN _` Trzeci argument sum() jest wartością początkową dla sumy elementów. Argument ten jest pominięty, więc domyślnie wynosi T(); w przypadku typu int i innych typów wbudowa- nych pseudokonstruktor realizuje inicjalizację zerem. Szablony jako parametry szablonów Trzeci rodzaj parametrów, jakich można użyć w szablonie, to inny szablon klasy. Może to wydawać się dziwne, gdyż szablony są typami, a parametry będące typami są dozwolo- ne; jeśli jednak w kodzie szablonu jako parametr ma być użyty inny szablon, kompi- lator musi najpierw „wiedzieć”, że parametrem jest właśnie szablon. Poniższy przy- kład pokazuje użycie szablonu jako parametru innego szyablonu:  6GOR6GORERR 2QMC\WLGWľ[EKGU\CDNQPWLCMQRCTCOGVTWU\CDNQPW KPENWFGEUVFFGH KPENWFGKQUVTGCO WUKPIPCOGURCEGUVF VGORNCVGENCUU6 ENCUU#TTC[] Y[Mđ[EKæIFCLæE[UKúRT\GFđWľCè GPWO]+0+6_ 6 FCVC UK\GAVECRCEKV[ UK\GAVEQWPV RWDNKE #TTC[ ] EQWPV FCVCPGY6=ECRCEKV[+0+6? _ `#TTC[ ]FGNGVG=?FCVC_ XQKFRWUJADCEM EQPUV6V ] KH EQWPVECRCEKV[ ] 2QYKúMU\GPKGVCDNKE[DC\QYGL UK\GAVPGY CR ECRCEKV[ 192 Część II ♦ Standardowa biblioteka C++ 6 PGY CVCPGY6=PGY CR? HQT UK\GAVKKEQWPV K PGY CVC=K?FCVC=K? FGNGVGFCVC FCVCPGY CVC ECRCEKV[PGY CR _ FCVC=EQWPV ?V _ XQKFRQRADCEM ] KH EQWPV  EQWPV _ 6 DGIKP ] TGVWTPFCVC _ 6 GPF ] TGVWTPFCVC EQWPV _ _ VGORNCVGENCUU6VGORNCVGENCUU ENCUU5GS ENCUU QPVCKPGT] 5GS6 UGS RWDNKE XQKFCRRGPF EQPUV6V ] UGSRWUJADCEM V  _ 6 DGIKP ] TGVWTPUGSDGIKP  _ 6 GPF ] TGVWTPUGSGPF  _ _ KPVOCKP ]  QPVCKPGTKPV#TTC[ EQPVCKPGT EQPVCKPGTCRRGPF   EQPVCKPGTCRRGPF   KPV REQPVCKPGTDGIKP  YJKNG REQPVCKPGTGPF EQWV R GPFN _` Szablon klasy Array to najzwyklejszy kontener zawierający sekwencję elementów. Szablon Container ma dwa parametry: typ przechowywanych obiektów oraz struktu- rę danych służącą do przechowywania danych. Poniższy wiersz implementacji klasy Container wymusza poinformowanie kompilatora, że parametr Seq jest szablonem: 5GS6 UGS Gdybyśmy nie zadeklarowali Seq jako parametru będącego szablonem, kompilator zgłosi błąd, twerdząc, że Seq nie jest szablonem, a jako takiego go używamy. W funkcji main() tworzona jest instancja szablonu Container w ten sposób, w klasie Array przecho- wywane były liczby całkowite — zatem w tym przykładyzie Seq oznacza Array. Rozdział 5. ♦ Wszystko o szablonach 193 Zauważ, że w tym wypadku nie jest konieczne nazywanie parametru Seq w deklaracji Container. Odpowiedni wiersz to: VGORNCVGENCUU6VGORNCVGENCUU ENCUU5GS Wprawdzie moglibyśmy zapisać: VGORNCVGENCUU6VGORNCVGENCUU7 ENCUU5GS lecz parametr U nie jest w ogóle potrzebny. Wszystko, co istotne, to to, że Seq jest szablonem klasy mającym pojedynczy parametr będący typem. Jest to analogia do pomijania nazw parametrów funkcji, kiedy nie są potrzebne, na przykład przy prze- ciążaniu operatora postinkrementacji: 6QRGTCVQT KPV  Słowo kluczowe int jest potrzebne jedynie ze względów formalnych, więc odpowia- dający mu argument nie musi mieć nazwy. Poniższy program korzysta z tablicy o ustalonej wielkości mającej dodatkowy para- metr szablonu odpowiadający wielkości tej tablicy:  6GOR6GORERR 9KGNQ\OKGPP[U\CDNQPLCMQRCTCOGVTU\CDNQPW KPENWFGEUVFFGH KPENWFGKQUVTGCO WUKPIPCOGURCEGUVF VGORNCVGENCUU6UK\GAV0 ENCUU#TTC[] 6FCVC=0? UK\GAVEQWPV RWDNKE #TTC[ ]EQWPV_ XQKFRWUJADCEM EQPUV6V ] KH EQWPV0 FCVC=EQWPV ?V _ XQKFRQRADCEM ] KH EQWPV  EQWPV _ 6 DGIKP ]TGVWTPFCVC_ 6 GPF ]TGVWTPFCVC EQWPV_ _ VGORNCVGENCUU6UK\GAV0VGORNCVGENCUUUK\GAV ENCUU5GS ENCUU QPVCKPGT] 5GS60 UGS RWDNKE XQKFCRRGPF EQPUV6V ]UGSRWUJADCEM V _ 6 DGIKP ]TGVWTPUGSDGIKP _ 6 GPF ]TGVWTPUGSGPF _ _ KPVOCKP ] EQPUVUK\GAV0  QPVCKPGTKPV0#TTC[ EQPVCKPGT 194 Część II ♦ Standardowa biblioteka C++ EQPVCKPGTCRRGPF   EQPVCKPGTCRRGPF   KPV REQPVCKPGTDGIKP  YJKNG REQPVCKPGTGPF EQWV R GPFN _` Znowu nazwy parametrów w deklaracji Seq wewnątrz deklaracji Containter są zbędne, ale potrzebne są dwa dodatkowe parametry do zadeklarowania pola seq, stąd na najwyż- szym poziomie pojawia się parametr N niebędący typem. Łączenie argumentów domyślnych z parametrami szablonów będących szablonami jest nieco bardziej problematyczne. Kiedy kompilator sprawdza parametr wewnętrzny parametru szablonu, nie są uwzględniane argumenty domyślne, wobec czego w celu uzyskania dokładnego dopasowania konieczne jest powtórzenie wartości domyślnych. Poniższy przykład wykorzystuje argument domyślny do szablonu Array o stałej wielko- ści, pokazuje też, jak sobie z tym dziwactwem języka radzić:  6GOR6GORERR ]DQT_ ]OUE_ ĐæE\GPKGRCTCOGVTÎYU\CDNQPÎYDúFæE[EJU\CDNQPCOK \CTIWOGPVCOKFQO[ħNP[OK KPENWFGEUVFFGH KPENWFGKQUVTGCO WUKPIPCOGURCEGUVF VGORNCVGENCUU6UK\GAV0 #TIWOGPVFQO[ħNP[ ENCUU#TTC[] 6FCVC=0? UK\GAVEQWPV RWDNKE #TTC[ ]EQWPV_ XQKFRWUJADCEM EQPUV6V ] KH EQWPV0 FCVC=EQWPV ?V _ XQKFRQRADCEM ] KH EQWPV  EQWPV _ 6 DGIKP ]TGVWTPFCVC_ 6 GPF ]TGVWTPFCVC EQWPV_ _ VGORNCVGENCUU6VGORNCVGENCUUUK\GAV ENCUU5GS ENCUU QPVCKPGT] 5GS6 UGS7ľ[VQCTIWOGPVWFQO[ħNPGIQ RWDNKE XQKFCRRGPF EQPUV6V ]UGSRWUJADCEM V _ 6 DGIKP ]TGVWTPUGSDGIKP _ 6 GPF ]TGVWTPUGSGPF _ _ KPVOCKP ]  QPVCKPGTKPV#TTC[ EQPVCKPGT EQPVCKPGTCRRGPF   Rozdział 5. ♦ Wszystko o szablonach 195 EQPVCKPGTCRRGPF   KPV REQPVCKPGTDGIKP  YJKNG REQPVCKPGTGPF EQWV R GPFN _` W poniższym wierszu trzeba włączyć domyślną wielkość yrówną 10: VGORNCVGENCUU6VGORNCVGENCUUUK\GAV ENCUU5GS Obie definicje, seq w Container i container, w main() wykorzystują wartości do- myślne. Jedynym sposobem użycia czegokolwiek innego niż wartość domyślna jest sko- rzystanie z metody z poprzedniego programu, TempTemp2.cpp. Jest to jedyny wyją- tek od podanej wcześniej zasady mówiącej, że argumenty domyślne powinny pojawiać się w danej jednostce kompilacji tylko raz. Wobec faktu, że wszystkie standardowe kontenery przechowujące elementy w formie sekwencji (vector, list oraz deque omówiono dokładnie w rozdziale 7.) mają domyślny argument allocator, powyższa technika jest przydatna, jeśli trzeba jedną z tych trzech metod uporządkowania przekazać jako parametr szablonu. W poniższym programie vector i list są przekazywane do dwóch instancji szablonu Container.  6GOR6GORERR ]DQT_ ]OUE_ 2T\GMC\CPKGUVCPFCTFQY[EJUGMYGPELKLCMQCTIWOGPVÎYU\CDNQPW KPENWFGKQUVTGCO KPENWFGNKUV KPENWFGOGOQT[  GMNCTCELCCNNQECVQT6 KPENWFGXGEVQT WUKPIPCOGURCEGUVF VGORNCVGENCUU6VGORNCVGENCUU7ENCUUCNNQECVQT7  ENCUU5GS ENCUU QPVCKPGT] 5GS6 UGS0KGLCYPKGUVQUQYCPGLGUVFQO[ħNPGCNNQECVQT6 RWDNKE XQKFRWUJADCEM EQPUV6V ]UGSRWUJADCEM V _ V[RGPCOG5GS6 KVGTCVQTDGIKP ]TGVWTPUGSDGIKP _ V[RGPCOG5GS6 KVGTCVQTGPF ]TGVWTPUGSGPF _ _ KPVOCKP ] 7ľ[LYGMVQTC  QPVCKPGTKPVXGEVQT X QPVCKPGT X QPVCKPGTRWUJADCEM   X QPVCKPGTRWUJADCEM   HQT XGEVQTKPV KVGTCVQTRX QPVCKPGTDGIKP  RX QPVCKPGTGPF  R ] EQWV RGPFN _ 7ľ[LNKUV[  QPVCKPGTKPVNKUV N QPVCKPGT N QPVCKPGTRWUJADCEM   N QPVCKPGTRWUJADCEM   196 Część II ♦ Standardowa biblioteka C++ HQT NKUVKPV KVGTCVQTRN QPVCKPGTDGIKP  RN QPVCKPGTGPF  R ] EQWV RGPFN _ _` W tym wypadku nazwaliśmy pierwszy parametr szablonu wewnętrznego Seq (ta na- zwa to U), gdyż alokatory w standardowych sekwencjach muszą być sparametryzo- wane tym samym typem, co obiekt ich używający. Poza tym, skoro domyślna wartość parametru allocator jest znana, możemy ją pominąć w dalszych odwołaniach do Seq T , jak w poprzednim programie. Jednak dokładne omówienie tego przykładu wymaga objaśnienia znaczenia słowa kluczowego typename. Słowo kluczowe typename Niech będzie dany program:  6[RGPCOGF+ ERR ]DQT_ 5đQYQ V[RGPCOG Wľ[YCPGLGUVLCMQRTGHKMUV[RÎY\CIPKGľFľQP[EJ VGORNCVGENCUU6 ENCUU:] )F[D[PKGD[đQV[RGPCOGRQYUVCđD[VWDđæF V[RGPCOG6KFK RWDNKE XQKFH ]KI _ _ ENCUU;] RWDNKE ENCUUKF] RWDNKE XQKFI ]_ _ _ KPVOCKP ] :; Z[ Z[H  _` W definicji szablonu zakłada się, że klasa T musi mieć pewnego rodzaju zagnieżdżony identyfikator id. Jednak id może być też statycznym polem T (a wtedy można byłoby na id wykonywać operacje bezpośrednio), natomiast nie można „tworzyć obiektu typu id”. Jednak właśnie to się tu dzieje — identyfikator id jest traktowany tak, jakby był typem zagnieżdżonym w T. W przypadku klasy Y id jest faktycznie typem zagnieżdżonym, ale bez słowa kluczowego typename kompilator nie wiedziałby o tym w chwili kompi- lowania X. Jeśli kompilator umożliwia traktowanie identyfikatora występującego w szablonie jako typu lub jako czegoś innego niż typ, przyjmie, że identyfikator jest czymś innym niż typ, czyli założy, że identyfikator odnosi się do obiektu (przy czym dane typów pro- stych też są traktowane jako obiekty), wyliczenia lub czegoś podobnego. Jednak kompilator nie założy, i nie może założyć, że jest to typ. Rozdział 5. ♦ Wszystko o szablonach 197 Wobec tego, że domyślne działanie kompilatora powoduje, że we wskazanych wyżej dwóch miejscach nie chodzi o typ, trzeba użyć słowa klyuczowego typename dla nazw zagnieżdżonych (wyjątkiem są listy inicjalizujące konstruktora, gdzie nie jest to ani potrzebne, ani dozwolone). W powyższym przykładzie kompilator widząc typename T::id, „wie” (dzięki słowu kluczowemu typename), że id odnosi się do typu zagnieżdżo- nego, więc może stworzyć obiekt tego typu. Cała ta zasada w formie skróconej brzmi: jeśli typ odnoszący się do kodu wewnątrz szablonu jest kwalifikowany parametrem szablonu będącym typem, powinien być po- przedzony słowem kluczowym typename, chyba że występuje w specyfikacji klasy bazowej lub na liście inicjalizacyjnej w tym samym zakresie (w obu tych przypadkach słowa tego nie można użyć). Powyższa dyskusja całkowicie objaśnia użycie słowa kluczowego typename w pro- gramie TempTemp4.cpp. Bez tego słowa kluczowego kompilator założyłby, że wy- rażenie Seq T ::iterator nie jest typem, podczas gdy dalej używane jest ono do zde- finiowania wartości zwracanej przez funkcje begin() i end(). W następnym przykładzie, zawierającym szablon funkcji pozwalający wydrukować dowolną standardową sekwencję C++, pokazano podobny spyosób użycia typename:  2TKPV5GSERR ]OUE_ (WPMELCFTWMWLæECV[RQYGUGMYGPELG KPENWFGKQUVTGCO KPENWFGNKUV KPENWFGOGOQT[ KPENWFGXGEVQT WUKPIPCOGURCEGUVF VGORNCVGENCUU6VGORNCVGENCUU7ENCUUCNNQECVQT7  ENCUU5GS XQKFRTKPV5GS 5GS6 UGS ] HQT V[RGPCOG5GS6 KVGTCVQTDUGSDGIKP  DUGSGPF  EQWV D GPFN _ KPVOCKP ] 2T\GVYCT\CPKGYGMVQTC XGEVQTKPV X XRWUJADCEM   XRWUJADCEM   RTKPV5GS X  2T\GVYCT\CPKGNKUV[ NKUVKPV NUV NUVRWUJADCEM   NUVRWUJADCEM   RTKPV5GS NUV  _` Znowu, gdyby nie słowo kluczowe typename, kompilator zinterpretowałby iterator jako statyczne pole należące do Seq T , czyli byłby to błąd składniowy — przecież typ jest wymagany. 198 Część II ♦ Standardowa biblioteka C++ Typedef i typename Nie wolno zakładać, że słowo kluczowe typename utworzy nową nazwę typu. Celem stosowania tego słowa jest wskazanie kompilatorowi, że tak zakwalifikowany identy- fikator ma być zinterpretowany jako typ. Wiersz: V[RGPCOG5GS6 KVGTCVQT+V mówi, że zmienna It jest zmienną typu Seq T ::iterator. Jeśli należałoby stworzyć nazwę nowego typu, jak zwykle trzeba użyć typedef: V[RGFGHV[RGPCOG5GS+V KVGTCVQT+V Użycie typename zamiast class Innym zastosowaniem słowa kluczowego typename jest możliwość użycia typename zamiast class na liście argumentów szablonu. Czasami powstający kod jest dzięki temu czytelniejszy:  7UKPI6[RGPCOGERR 7ľ[EKG V[RGPCOG PCNKħEKGCTIWOGPVÎYU\CDNQPW VGORNCVGV[RGPCOG6 ENCUU:]_ KPVOCKP ] :KPV Z _` Prawdopodobnie nieczęsto spotkasz się z takim użyciem słowa kluczowego typename, gdyż słowo to zostało dodane do języka dość długo pyo zdefiniowaniu szablonów. Użycie słowa kluczowego template jako wskazówki Tak jak słowo kluczowe typename pomaga kompilatorowi w sytuacjach, kiedy nie spodziewa się on identyfikatora typu, istnieje też potencjalna trudność związana z lekse- mami niebędącymi identyfikatorami, jak znaki i ; czasami oznaczają one symbole mniejszości i większości, a czasami ograniczają listy parametrów szablonu. W ramach przykładu skorzystajmy jeszcze raz z klasy bitset:   QV6GORNCVGERR 2QMC\WLGWľ[EKGMQPUVTWMELKVGORNCVG KPENWFGDKVUGV KPENWFGEUVFFGH KPENWFGKQUVTGCO KPENWFGUVTKPI WUKPIPCOGURCEGUVF VGORNCVGENCUUEJCT6UK\GAV0 DCUKEAUVTKPIEJCT6 DKVUGV6Q5VTKPI EQPUVDKVUGV0 DU ] TGVWTPDUVGORNCVGVQAUVTKPIEJCT6EJCTAVTCKVUEJCT6  CNNQECVQTEJCT6   _ Rozdział 5. ♦ Wszystko o szablonach 199 KPVOCKP ] DKVUGV DU DUUGV   DUUGV   EQWVDUGPFN UVTKPIUDKVUGV6Q5VTKPIEJCT DU  EQWVUGPFN _` Klasa bitset realizuje konwersję na obiekt-łańcuch za pomocą funkcji składowej to_st- ring. Aby obsłużyć różne klasy łańcuchów, to_string sama jest szablonem, zgodnie z definicją szablonu basic_string omawianą w rozdziale 3. Deklaracja to_string w ramach bitset wygląda następująco: VGORNCVGENCUUEJCT6ENCUUVTCKVUENCUU#NNQECVQT DCUKEAUVTKPIEJCT6VTCKVU#NNQECVQT VQAUVTKPI EQPUV Nasz pokazany powyższej szablon funkcji bitsetToString() pozwala zwracać obiekty bitset jako różnego rodzaju łańcuchy znaków. Aby uzyskać, na przykład, łańcuch z szero- kimi znakami, należy wywołanie zapisać następująco: YUVTKPIUDKVUGV6Q5VTKPIYEJCTAV DU  Zauważ, że basic_string korzysta z domyślnych argumentów szablonu, więc nie mu- simy powtarzać argumentów char_traits i allocator w wartości zwracanej. Niestety, bitset::to_string nie używa argumentów domyślnych. Użycie bitsetToString char (bs) jest wygodniejsze niż pisanie za każdym razem całego bs.template to_string char, char_traits, allocator char (). Instrukcja return w funkcji bitsetToString() zawiera słowo kluczowe template w dość dziwnym miejscu — zaraz po operatorze „kropka” zastosowanym do obiektu bs typu bitset. Wynika to stąd, że kiedy analizowany jest szablon, znak znajdujący się za napisem to_string zostałby interpretowany jako operator mniejszości, a nie początek lub lista argumentów szablonu. W punkcie „Odszukiwanie nazw” w dalszej części roz- działu słowo kluczowe template użyte w tym kontekście informuje kompilator, że dalej następuje nazwa szablonu; dzięki temu znak zostanie zinterpretowany prawidłowo. Takie samo rozumowanie dotyczy operatorów - i :: stosowanych do szablonów. Tak jak w przypadku słowa kluczowego template opisana technika unikania wieloznaczności może być używana jedynie w szablonach2. Szablony składowe Szablon funkcji bitset::to_string() jest przykładem szablonu składowego czyli szablonu zadeklarowanego w innej klasie lub szablonie klasy. Dzięki temu można tworzyć rozmaite kombinacje niezależnych argumentów szablonów. Praktyczny przykład znaleźć można w szablonie klas complex w standardowej bibliotece C++. Szablon complex ma pa- rametr będący typem, który pozwala zadeklarować typ zmiennoprzecinkowy służący 2 Komitet standaryzacyjny C++ rozważa rezygnację z klauizuli „jedynie w szablonach”, jeśli chodzi o unikanie wieloznaczności. Niektóre kompilatory już teiraz pozwalają na stosowanie takich podpowiedzi poza szablonami. 200 Część II ♦ Standardowa biblioteka C++ do przechowywania części rzeczywistej i urojonej liczby zespolonej. Poniższy frag- ment kodu z biblioteki standardowej pokazuje konstruktor szablonu składowego sza- blonu klasy complex: VGORNCVGV[RGPCOG6 ENCUUEQORNGZ] RWDNKE VGORNCVGENCUU: EQORNGZ EQPUVEQORNGZ:   Standardowy szablon complex ma już gotowe specjalizacje z parametrem T o warto- ści
Pobierz darmowy fragment (pdf)

Gdzie kupić całą publikację:

Thinking in C++. Edycja polska. Tom 2
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ą: