Cyfroteka.pl

klikaj i czytaj online

Cyfro
Czytomierz
00144 008289 11000320 na godz. na dobę w sumie
C++. Inżynieria programowania - książka
C++. Inżynieria programowania - książka
Autor: Liczba stron: 1088
Wydawca: Helion Język publikacji: polski
ISBN: 83-7361-171-1 Data wydania:
Lektor:
Kategoria: ebooki >> komputery i informatyka >> programowanie >> c++ - programowanie
Porównaj ceny (książka, ebook, audiobook).

Naucz się języka C++ w najlepszy sposób:
poznając go z punktu widzenia inżynierii programowania

Książka Wiktora Shterna zatytułowana 'C++. Inżynieria programowania' stosuje wyjątkowy sposób nauki języka C++ przeznaczony dla programistów mających doświadczenie w dowolnym języku programowania: prezentuje możliwość zastosowania w C++ najlepszych technik programistycznych oraz metodologii inżynierii programowania. Nawet jeżeli już wcześniej wykorzystywałeś język C++, ta wyczerpująca książka przedstawi sposób tworzenia poprawniejszego kodu, łatwiejszego do utrzymania i modyfikacji.

Książka niniejsza uczy zasad programowania obiektowego przed samą nauką języka, co pozwala wykorzystać wszystkie zalety OOP do tworzenia poprawnych aplikacji. Udoskonalisz znajomość kluczowych składników standardu ANSI/ISO C++ rozpatrywanych z punktu widzenia inżyniera: klas, metod, modyfikatorów const, dynamicznego zarządzania pamięcią, złożeń klas, dziedziczenia, polimorfizmu, operacji wejścia-wyjścia i wielu innych. Jeżeli pragniesz tworzyć w języku C++ najlepsze programy, musisz projektować, myśleć i programować stosując najlepsze obecnie praktyki inżynierii programowania. Lektura książki 'C++. Inżynieria programowania' pomoże Ci w tym.

Książka 'C++. Inżynieria programowania' kładzie nacisk na:

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 C++. In¿ynieria programowania Autor: Victor Shtern T³umaczenie: Daniel Kaczmarek (rozdz. 1 – 6), Adam Majczak (rozdz. 7 – 11), Rafa³ Szpoton (rozdz. 12 – 19) ISBN: 83-7361-171-1 Tytu³ orygina³u: Core C++: A Software Engineering Approach Format: B5, stron: 1084 Naucz siê jêzyka C++ w najlepszy sposób: poznaj¹c go z punktu widzenia in¿ynierii programowania • Demonstruje praktyczne techniki stosowane przez zawodowych programistów • Zawiera poprawny, gruntownie przetestowany przyk³adowy kod ĥród³owy programów oraz przyk³ady zaczerpniête z praktyki • Skoncentrowana na nowoczesnych technologiach, które musz¹ poznaæ programiġci • Zawiera rady profesjonalistów, które pozwol¹ czytelnikowi tworzyæ najlepsze programy Ksi¹¿ka Wiktora Shterna zatytu³owana „C++. In¿ynieria programowania” stosuje wyj¹tkowy sposób nauki jêzyka C++ przeznaczony dla programistów maj¹cych doġwiadczenie w dowolnym jêzyku programowania: prezentuje mo¿liwoġæ zastosowania w C++ najlepszych technik programistycznych oraz metodologii in¿ynierii programowania. Nawet je¿eli ju¿ wczeġniej wykorzystywa³eġ jêzyk C++, ta wyczerpuj¹ca ksi¹¿ka przedstawi sposób tworzenia poprawniejszego kodu, ³atwiejszego do utrzymania i modyfikacji. Ksi¹¿ka niniejsza uczy zasad programowania obiektowego przed sam¹ nauk¹ jêzyka, co pozwala wykorzystaæ wszystkie zalety OOP do tworzenia poprawnych aplikacji. Udoskonalisz znajomoġæ kluczowych sk³adników standardu ANSI/ISO C++ rozpatrywanych z punktu widzenia in¿yniera: klas, metod, modyfikatorów const, dynamicznego zarz¹dzania pamiêci¹, z³o¿eñ klas, dziedziczenia, polimorfizmu, operacji wejġcia-wyjġcia i wielu innych. Je¿eli pragniesz tworzyæ w jêzyku C++ najlepsze programy, musisz projektowaæ, myġleæ i programowaæ stosuj¹c najlepsze obecnie praktyki in¿ynierii programowania. Lektura ksi¹¿ki „C++. In¿ynieria programowania” pomo¿e Ci w tym. Ksi¹¿ka „C++. In¿ynieria programowania” k³adzie nacisk na: • Prezentacjê zastosowañ zasad in¿ynierii programowania w programach pisanych w C++ • Tworzenie kodu ³atwego do póĥniejszych modyfikacji • Praktyczne zrozumienie zasad programowania obiektowego przed nauk¹ samego jêzyka • Przedstawienie najnowszych cech standardu ANSI/ISO C++ • Zaprezentowanie setek realistycznych przyk³adów kodu programów Wiktor Shtern jest profesorem wyk³adaj¹cym w college’u przy uniwersytecie w Bostonie, uznawanym za jedn¹ z najlepszych w Stanach Zjednoczonych szkó³ dla osób pracuj¹cych zawodowo. Oprócz wyk³adów z jêzyka C++ na poziomie uniwersyteckim, Shtern prowadzi równie¿ zajêcia praktyczne dla doġwiadczonych programistów. Dan Costello jest in¿ynierem oprogramowania w firmie GE Marquette Medical Systems Spis treści Wprowadzenie 15 Co odróżnia tę książkę od innych książek o C++? ...................................................a.... 15 Dla kogo jest przeznaczona ta książka? ...................................................a.................. 17 Jak korzystać z tej książki? ...................................................a.................................... 17 Konwencje stosowane w książce...................................................a............................ 18 Dostęp do kodów źródłowych ...................................................a................................. 19 Część I Wprowadzenie do programowania w języku C++ 21 Rozdział 1. Podejście zorientowane obiektowo — co je wyróżnia? 23 Źródła kryzysu oprogramowania...................................................a.............................. 24 Rozwiązanie 1. — wyeliminowanie programistów ...................................................a..... 28 Rozwiązanie 2. — ulepszone techniki zarządzania ...................................................a... 30 Metoda wodospadu ...................................................a......................................... 31 Szybkie tworzenie prototypu...................................................a.............................. 32 Rozwiązanie 3. — projektowanie złożonego i rozwlekłego języka .................................. 33 Podejście zorientowane obiektowo — czy dostaniemy coś za nic?................................ 34 Na czym polega praca projektanta?...................................................a................... 35 Jakość projektu — spójność...................................................a............................. 37 Jakość projektu — łączność ...................................................a............................. 37 Jakość projektu — wiązanie danych i funkcji ...................................................a...... 38 Jakość projektu — ukrywanie informacji i kapsułkowanie ....................................... 40 Sprawa projektowania — konflikty nazewnictwa ...................................................a. 41 Sprawa projektowania — inicjalizacja obiektu ...................................................a.... 42 Czym jest obiekt? ...................................................a............................................ 43 Zalety stosowania obiektów...................................................a.............................. 44 Charakterystyka języka C++ ...................................................a................................... 45 Cele języka C — wydajność, czytelność, piękno i przenośność................................ 45 Cele języka C++ — klasy ze wsteczną zgodnością z C............................................ 47 Podsumowanie ...................................................a...................................................a.. 50 Rozdział 2. Szybki start — krótki przegląd języka C++ 53 Podstawowa struktura programu ...................................................a............................ 54 Dyrektywy preprocesora...................................................a......................................... 56 Komentarze...................................................a...................................................a....... 60 Deklaracje i definicje ...................................................a............................................. 63 Instrukcje i wyrażenia ...................................................a............................................ 69 Funkcje i wywołania funkcji ...................................................a.................................... 77 6 C++. Inżynieria programowania Klasy ...................................................a...................................................a................ 86 Praca z narzędziami programistycznymi...................................................a................... 90 Podsumowanie ...................................................a...................................................a.. 94 Rozdział 3. Praca z danymi i wyrażeniami w C++ 95 Wartości i ich typy...................................................a................................................. 96 Typy całkowitoliczbowe ...................................................a.......................................... 98 Kwalifikatory typu całkowitoliczbowego ...................................................a............ 100 Znaki ...................................................a...................................................a......... 104 Wartości logiczne...................................................a........................................... 106 Typy liczb zmiennoprzecinkowych...................................................a.......................... 107 Praca z wyrażeniami C++ ...................................................a..................................... 109 Operatory o wysokim priorytecie...................................................a...................... 110 Operatory arytmetyczne ...................................................a.................................. 111 Operatory przesunięcia...................................................a................................... 114 Bitowe operatory logiczne...................................................a............................... 115 Operatory relacji i równości...................................................a............................. 118 Operatory logiczne ...................................................a......................................... 120 Operatory przypisania...................................................a..................................... 122 Operator warunkowy...................................................a....................................... 123 Operator przecinkowy ...................................................a..................................... 124 Wyrażenia mieszane — ukryte zagrożenia ...................................................a............. 125 Podsumowanie ...................................................a...................................................a 131 Rozdział 4. Sterowanie przebiegiem programu C++ 133 Instrukcje i wyrażenia ...................................................a.......................................... 134 Instrukcje warunkowe...................................................a.......................................... 136 Standardowe formy instrukcji warunkowych...................................................a...... 136 Częste błędy w instrukcjach warunkowych...................................................a........ 140 Zagnieżdżone instrukcje warunkowe i ich optymalizacja ....................................... 152 Iteracje ...................................................a...................................................a........... 158 Zastosowanie pętli WHILE ...................................................a.............................. 159 Iteracje w pętli DO-WHILE ...................................................a............................... 167 Iteracje w pętli FOR...................................................a........................................ 170 Instrukcje skoków w C++...................................................a..................................... 173 Instrukcja BREAK...................................................a........................................... 174 Instrukcja CONTINUE......................................a...................................................a 177 Instrukcja GOTO ...................................................a............................................ 178 Instrukcje skoków RETURN i EXIT...................................................a.................... 179 Instrukcja SWITCH ...................................................a......................................... 183 Podsumowanie ...................................................a...................................................a 186 Rozdział 5. Agregacja za pomocą typów danych zdefiniowanych przez programistę 187 Tablice jako agregaty homogeniczne...................................................a..................... 188 Tablice jako wektory wartości...................................................a.......................... 188 Definiowanie tablic C++ ...................................................a................................. 190 Operacje na tablicach ...................................................a.................................... 193 Sprawdzanie poprawności indeksów...................................................a................ 194 Tablice wielowymiarowe ...................................................a................................. 197 Definiowanie tablic znaków...................................................a............................. 200 Operacje na tablicach znaków...................................................a......................... 202 Funkcje łańcuchowe a błędy pamięci ...................................................a............... 204 Spis treści 7 Dwuwymiarowe tablice znaków...................................................a........................ 208 Przepełnienie tablic w algorytmach je wypełniających ........................................... 210 Definiowanie typów tablicowych ...................................................a...................... 214 Struktury jako agregaty heterogeniczne...................................................a................. 216 Definiowanie struktur jako typów zdefiniowanych przez programistę ...................... 216 Tworzenie i inicjalizowanie zmiennych strukturalnych ........................................... 217 Struktury hierarchiczne i ich komponenty ...................................................a......... 219 Operacje na zmiennych strukturalnych...................................................a............. 220 Definiowanie struktur w programach złożonych z wielu plików ............................... 222 Unie, typy wyliczeniowe i pola bitowe ...................................................a.................... 223 Unie ...................................................a...................................................a.......... 223 Typy wyliczeniowe ...................................................a.......................................... 227 Pola bitowe ...................................................a...................................................a 229 Podsumowanie ...................................................a...................................................a 233 Rozdział 6. Zarządzanie pamięcią — stos i sterta 235 Zasięg nazw jako narzędzie współpracy...................................................a................. 236 Zasięgi leksykalne C++ ...................................................a.................................. 236 Konflikty nazw w tym samym zasięgu ...................................................a.............. 237 Stosowanie takich samych nazw w zasięgach niezależnych .................................. 241 Stosowanie takich samych nazw w zasięgach zagnieżdżonych .............................. 241 Zasięg zmiennych pętli...................................................a................................... 246 Zarządzanie pamięcią — klasy pamięci...................................................a................. 246 Zmienne automatyczne ...................................................a.................................. 248 Zmienne zewnętrzne ...................................................a...................................... 251 Zmienne statyczne...................................................a......................................... 257 Zarządzanie pamięcią — zastosowanie sterty...................................................a........ 261 Wskaźniki C++ jako zmienne o określonym typie ................................................. 263 Alokowanie pamięci na stercie...................................................a........................ 268 Tablice i wskaźniki ...................................................a......................................... 273 Tablice dynamiczne...................................................a........................................ 276 Struktury dynamiczne ...................................................a..................................... 290 Operacje wejścia i wyjścia na plikach...................................................a.................... 300 Zapisywanie do pliku...................................................a...................................... 301 Odczyt z pliku ...................................................a................................................ 304 Plikowe obiekty wejścia-wyjścia ...................................................a....................... 308 Podsumowanie ...................................................a...................................................a 311 Część II Programowanie obiektowe w C++ 313 Rozdział 7. Programowanie w C++ z zastosowaniem funkcji 315 Funkcje w C++ jako narzędzie modularyzacji programu .............................................. 317 Deklaracje funkcji ...................................................a.......................................... 318 Definicje funkcji ...................................................a............................................. 319 Wywołania funkcji ...................................................a.......................................... 320 Promocja i konwersja argumentów funkcji ...................................................a............. 323 Przekazywanie parametrów do funkcji w C++ ...................................................a......... 326 Przekazanie parametru przez wartość ...................................................a.............. 326 Przekazanie parametrów poprzez wskaźnik ...................................................a...... 328 Przekazanie parametrów do funkcji charakterystycznej dala C++ — poprzez referencję...................................................a................................ 336 Struktury...................................................a...................................................a.... 341 8 C++. Inżynieria programowania Tablice...................................................a...................................................a....... 348 Więcej o konwersjach typów ...................................................a........................... 352 Zwracanie wartości z funkcji ...................................................a........................... 355 Funkcje wplecione — inline...................................................a.................................. 361 Parametry funkcji z wartościami domyślnymi ...................................................a......... 364 Przeciążanie nazw funkcji...................................................a..................................... 370 Podsumowanie ...................................................a...................................................a 377 Rozdział 8. Programowanie obiektowe z zastosowaniem funkcji 381 Kohezja...................................................a...................................................a........... 385 Sprzęganie ...................................................a...................................................a...... 386 Niejawne sprzężenie ...................................................a...................................... 386 Jawne sprzężenie...................................................a........................................... 390 Jak zredukować intensywność sprzęgania? ...................................................a...... 395 Hermetyzacja danych...............................................a............................................... 400 Ukrywanie danych ...................................................a............................................... 407 Większy przykład hermetyzacji danych...................................................a................... 413 Wady hermetyzacji danych przy użyciu funkcji ...................................................a........ 422 Podsumowanie ...................................................a...................................................a 425 Rozdział 9. Klasy w C++ jako jednostki modularyzacji 427 Podstawowa składnia definicji klasy ...................................................a..................... 430 Połączenie danych i operacji ...................................................a........................... 430 Eliminowanie konfliktów nazw ...................................................a......................... 435 Implementacja kodów metod poza definicją klasy................................................ 439 Definiowane obiektów przechowywanych w pamięci różnych kategorii.................... 443 Kontrolowanie dostępu do komponentów klasy ...................................................a..... 444 Inicjowanie obiektów danej klasy...................................................a.......................... 451 Konstruktory — jako metody...................................................a........................... 452 Konstruktory domyślne...................................................a................................... 455 Konstruktory kopiujące...................................................a................................... 457 Konstruktory konwersji ...................................................a................................... 461 Destruktory ...................................................a...................................................a 463 Co i kiedy, czyli co naprawdę robią konstruktory i destruktory ............................... 468 Widoczność nazw w obrębie klasy i przesłanianie nazw przy zagnieżdżaniu ............ 469 Zarządzanie pamięcią za pomocą operatorów i wywołań funkcji ............................ 472 Zastosowanie w kodzie klienta obiektów zwracanych przez funkcje............................. 476 Zwrot wskaźników i referencji...................................................a.......................... 476 Zwrot obiektów z funkcji ...................................................a................................. 479 Więcej o stosowaniu słowa kluczowego const ...................................................a....... 482 Statyczne komponenty klas ...................................................a................................. 488 Zastosowanie zmiennych globalnych jako charakterystyk klas .............................. 489 Czwarte znaczenie słowa kluczowego static ...................................................a..... 491 Inicjowanie statycznych pól danych...................................................a.................. 492 Statyczne metody ...................................................a.......................................... 493 Podsumowanie ...................................................a...................................................a 497 Rozdział 10. Funkcje operatorowe — jeszcze jeden dobry pomysł 499 Przeciążanie operatorów ...................................................a...................................... 501 Ograniczenia w przeciążaniu operatorów ...................................................a............... 510 Które operatory nie mogą być poddane przeciążaniu? .......................................... 510 Ograniczenia typów wartości zwracanych przez funkcje operatorowe...................... 512 Spis treści 9 Ograniczenia liczby parametrów funkcji operatorowych ......................................... 514 Ograniczenia wynikające z priorytetu operatorów ................................................. 515 Przeciążone operatory jako komponenty składowe klas ............................................. 516 Zastępowanie funkcji globalnej metodą należącą do klasy ................................... 516 Zastosowanie komponentów klas w operacjach łańcuchowych ............................. 519 Zastosowanie słowa kluczowego const...................................................a............ 521 Analiza przedmiotowa — ułamki zwykłe...................................................a................. 523 Mieszane typy danych jako parametry...................................................a................... 533 Funkcje zaprzyjaźnione „friend” ...................................................a............................ 541 Podsumowanie ...................................................a...................................................a 556 Rozdział 11. Konstruktory i destruktory — potencjalne problemy 557 Więcej o przekazywaniu obiektów poprzez wartość...................................................a... 559 Przeciążanie operatorów w klasach nie będących klasami numerycznymi .................... 566 Klasa String ...................................................a.................................................. 567 Dynamiczne zarządzanie pamięcią na stercie ...................................................a... 569 Ochrona danych na stercie należących do obiektu od strony kodu klienta.............. 574 Przeciążony operator konkatenacji łańcuchów znakowych ..................................... 574 Zapobieganie wyciekom pamięci ...................................................a..................... 577 Ochrona integralności programu...................................................a...................... 578 Jak „stąd” przejść „tam”? ...................................................a.............................. 583 Więcej o konstruowaniu kopii obiektów ...................................................a................. 585 Sposób na zachowanie integralności programu ...................................................a 585 Semantyka referencji i semantyka wartości...................................................a...... 590 Konstruktor kopiujący definiowany przez programistę........................................... 592 Zwrot poprzez wartość...................................................a.................................... 597 Ograniczenia skuteczności konstruktorów kopiujących ......................................... 600 Przeciążenie operatora przypisania ...................................................a....................... 601 Problem z dodaną przez kompilator obsługą operatora przypisania ....................... 602 Przeciążenie przypisania — wersja pierwsza (z wyciekiem pamięci) ....................... 603 Przeciążenie przypisania — wersja następna (samoprzypisanie) ........................... 604 Przeciążenie przypisania — jeszcze jedna wersja (wyrażenia łańcuchowe)................... 605 Pierwszy środek zapobiegawczy — więcej przeciążania ........................................ 610 Drugi środek zapobiegawczy — zwrot wartości poprzez referencję......................... 611 Rozważania praktyczne — jak chcielibyśmy to zaimplementować? ............................. 612 Podsumowanie ...................................................a...................................................a 616 Część III Programowanie obiektowe przy wykorzystaniru agregacji oraz dziedziczenia 619 Rozdział 12. Klasy złożone — pułapki i zalety 621 Wykorzystywanie obiektów jako danych składowych .................................................. 623 Składnia C++ dotycząca złożenia klas ...................................................a............. 625 Dostęp do danych składowych komponentów klasy ............................................. 626 Dostęp do danych składowych parametrów metody ............................................. 629 Inicjalizacja obiektów złożonych...................................................a............................ 630 Wykorzystanie domyślnych konstruktorów komponentów...................................... 632 Wykorzystanie listy inicjalizującej składowe ...................................................a...... 638 Dane składowe ze specjalnymi właściwościami ...................................................a..... 644 Stałe dane składowe ...................................................a..................................... 645 Dane składowe określone przez referencje ...................................................a...... 646 10 C++. Inżynieria programowania Wykorzystywanie obiektów w charakterze danych składowych ich własnej klasy ..... 649 Wykorzystywanie statycznych danych składowych w charakterze składowych ich własnych klas.................................................. 651 Klasy kontenerów..............................................a...................................................a.. 654 Klasy zagnieżdżone...................................................a........................................ 670 Klasy zaprzyjaźnione ...................................................a...................................... 673 Podsumowanie ...................................................a...................................................a 676 Rozdział 13. Klasy podobne — jak je traktować? 677 Traktowanie podobnych klas ...................................................a................................ 679 Łączenie cech podklas w jednej klasie...................................................a............. 681 Przekazywanie odpowiedzialności za integralność programu do klasy serwera........ 683 Oddzielenie klas dla każdego rodzaju obiektu serwera ......................................... 688 Wykorzystywanie dziedziczenia w języku C++ w celu łączenia powiązanych klas...... 691 Składnia dziedziczenia w języku C++ ...................................................a.................... 694 Różne tryby dziedziczenia z klasy bazowej ...................................................a........ 695 Definiowanie oraz wykorzystywanie obiektów klas bazowych oraz klas pochodnych ....699 Dostęp do usług klasy bazowej oraz pochodnej ...................................................a..... 701 Dostęp do komponentów bazowych w obiektach klasy pochodnej .............................. 706 Dziedziczenie publiczne...................................................a.................................. 706 Dziedziczenie chronione ...................................................a................................. 711 Dziedziczenie prywatne...................................................a................................... 716 Zwiększanie dostępu do składowych bazowych w klasie pochodnej....................... 718 Domyślny tryb dziedziczenia...................................................a............................ 720 Reguły zakresu widoczności oraz rozwiązywanie nazw przy stosowaniu dziedziczenia ... 722 Przeciążanie oraz ukrywanie nazw ...................................................a................... 725 Wywoływanie metody klasy bazowej ukrytej przez klasę pochodną......................... 729 Wykorzystanie dziedziczenia w celu rozwoju programu.......................................... 733 Konstruktory oraz destruktory klas pochodnych ...................................................a..... 736 Wykorzystanie list inicjalizujących w konstruktorach klas pochodnych.................... 740 Destruktory w przypadku dziedziczenia ...................................................a............ 743 Podsumowanie ...................................................a...................................................a 745 Rozdział 14. Wybór pomiędzy dziedziczeniem a złożeniem 747 Wybór techniki wielokrotnego wykorzystywania kodu ................................................. 749 Przykład relacji typu klient-serwer pomiędzy klasami ............................................ 749 Ponowne wykorzystanie kodu poprzez ludzką inteligencjęa — po prostu zrób to jeszcze raz...................................................a................. 753 Ponowne użycie kodu poprzez kupowanie usług...................................................a 755 Ponowne wykorzystanie kodu poprzez dziedziczenie............................................. 759 Dziedziczenie wraz z ponownym zdefiniowaniem funkcji........................................ 764 Plusy i minusy dziedziczenia oraz złożenia ...................................................a....... 766 Język UML ...................................................a...................................................a....... 768 Cele stosowania języka UML...................................................a........................... 768 Podstawy UML — Notacja klas ...................................................a....................... 772 Podstawy UML — notacja relacji ...................................................a..................... 773 Podstawy UML — notacja dla agregacji oraz uogólnienia...................................... 774 Podstawy UML — notacja krotności ...................................................a................ 776 Studium przypadku — wypożyczalnia filmów...................................................a.......... 778 Klasy oraz ich skojarzenia ...................................................a.............................. 779 Spis treści 11 Widoczność klasy oraz podział odpowiedzialności ...................................................a.. 796 Widoczność klas oraz relacje pomiędzy klasami .................................................. 797 Przekazywanie odpowiedzialności do klas serwera............................................... 799 Stosowanie dziedziczenia ...................................................a............................... 801 Podsumowanie ...................................................a...................................................a 804 Część IV Zaawansowane wykorzystanie języka C++ 805 Rozdział 15. Funkcje wirtualne oraz inne zaawansowane nsposoby wykorzystania dziedziczenia 807 Konwersje pomiędzy klasami niepowiązanymi...................................................a........ 809 Ścisła oraz słaba kontrola typów ...................................................a..................... 812 Konstruktory konwertujące ...................................................a............................. 813 Rzutowania pomiędzy wskaźnikami (lub referencjami) .......................................... 815 Operatory konwersji ...................................................a....................................... 816 Konwersje pomiędzy klasami powiązanymi poprzez dziedziczenie ............................... 817 Konwersje bezpieczne oraz niebezpieczne ...................................................a....... 818 Konwersje wskaźników oraz referencji do obiektów.............................................. 824 Konwersje wskaźników oraz referencji występujących w charakterze argumentów... 833 Funkcje wirtualne — kolejny nowy pomysł ...................................................a............. 840 Wiązanie dynamiczne — podejście tradycyjne ...................................................a.. 843 Wiązanie dynamiczne — podejście obiektowe ...................................................a.. 852 Wiązanie dynamiczne — funkcje wirtualne ...................................................a....... 861 Wiązanie dynamiczne oraz statyczne ...................................................a............... 865 Funkcje czysto wirtualne...................................................a................................. 869 Funkcje wirtualne — destruktory ...................................................a..................... 873 Wielodziedziczenie — kilka klas bazowych ...................................................a............ 875 Wielodziedziczenie — reguły dostępu ...................................................a.............. 877 Konwersje pomiędzy klasami ...................................................a.......................... 878 Wielodziedziczenie — konstruktory oraz destruktory ............................................ 880 Wielodziedziczenie — niejednoznaczności...................................................a........ 881 Wielodziedziczenie — grafy skierowane ...................................................a........... 884 Czy wielodziedziczenie jest przydatne?...................................................a............. 885 Podsumowanie ...................................................a...................................................a 886 Rozdział 16. Zaawansowane wykorzystanie przeciążania operatorów 889 Przeciążanie operatorów — krótki wstęp ...................................................a............... 890 Operatory jednoargumentowe...................................................a............................... 898 Operatory inkrementacji oraz dekrementacji ...................................................a..... 899 Przyrostkowe operatory przeciążone ...................................................a................ 907 Operatory konwersji ...................................................a....................................... 910 Operatory indeksowania oraz wywołania funkcji ...................................................a..... 918 Operator indeksowania ...................................................a.................................. 918 Operator wywołania funkcji ...................................................a............................. 927 Operatory wejścia-wyjścia ...................................................a.................................... 933 Przeciążanie operatora ...................................................a.............................. 933 Przeciążanie operatora ...................................................a.............................. 937 Podsumowanie ...................................................a...................................................a 939 12 C++. Inżynieria programowania Rozdział 17. Szablony — jeszcze jedno narzędzie projektowania 941 Prosty przykład projektowania klas przeznaczonych do wielokrotnego wykorzystania......... 942 Składnia definicji klasy szablonu ...................................................a.......................... 951 Specyfikacja klasy szablonu ...................................................a........................... 952 Konkretyzacja szablonu ...................................................a.................................. 953 Implementacja funkcji szablonu ...................................................a...................... 955 Szablony zagnieżdżone...................................................a................................... 962 Klasy szablonów z wieloma parametrami ...................................................a.............. 963 Kilka parametrów określających typ...................................................a................. 963 Szablony z parametrami określonymi za pomocą stałego wyrażenia ...................... 967 Związki pomiędzy konkretyzacjami klas szablonów...................................................a. 970 Zaprzyjaźnione klasy szablonów ...................................................a...................... 970 Zagnieżdżone klasy szablonów...................................................a........................ 974 Szablony ze składowymi statycznymi ...................................................a............... 977 Specjalizacje szablonów ...................................................a...................................... 979 Funkcje szablonowe ...................................................a............................................ 983 Podsumowanie ...................................................a...................................................a 985 Rozdział 18. Programowanie przy użyciu wyjątków 987 Prosty przykład obsługi wyjątków ...................................................a.......................... 988 Składnia wyjątków w języku C++...................................................a........................... 995 Generowanie wyjątków ...................................................a................................... 997 Przechwytywanie wyjątków ...................................................a.............................. 998 Deklaracja wyjątków...................................................a..................................... 1005 Przekazywanie wyjątków ...................................................a............................... 1007 Wykorzystywanie wyjątków z obiektami.............................................a...................... 1011 Składnia generowania, deklaracji oraz przechwytywania obiektów ....................... 1011 Wykorzystywanie dziedziczenia podczas stosowania wyjątków ............................ 1015 Wyjątki zdefiniowane w bibliotece standardowej ................................................ 1020 Operatory rzutowania...................................................a......................................... 1021 Operator static_cast ...................................................a.................................... 1022 Operator reinterpret_cast ...................................................a............................. 1026 Operator const_cast ...................................................a.................................... 1026 Operator dynamic_cast ...................................................a................................ 1029 Operator typeid...................................................a............................................ 1032 Podsumowanie ...................................................a................................................. 1033 Rozdział 19. Czego nauczyłeś się dotychczas? 1035 C++ jako tradycyjny język programowania...................................................a............ 1036 Wbudowane typy danych języka C++...................................................a.............. 1036 Wyrażenia języka C++ ...................................................a.................................. 1038 Przepływ kontroli w programie C++ ...................................................a................ 1040 C++ jako język modułowy...................................................a................................... 1041 Typy agregacyjne języka C++ — tablice...................................................a.......... 1042 Typy agregacyjne języka C++ — struktury, unie, wyliczenia ................................. 1043 Funkcje C++ jako narzędzia modularyzacji...................................................a...... 1044 Funkcje C++ — przekazywanie parametrów...................................................a.... 1046 Zakres widoczności oraz klasy pamięci w języku C++......................................... 1048 C++ jako język obiektowy...................................................a................................... 1049 Klasy języka C++ ...................................................a......................................... 1050 Konstruktory, destruktory oraz operatory przeciążone......................................... 1051 Spis treści 13 Składanie klas oraz dziedziczenie ...................................................a................. 1052 Funkcje wirtualne oraz klasy abstrakcyjne ...................................................a...... 1054 Szablony ...................................................a...................................................a.. 1055 Wyjątki...................................................a...................................................a..... 1056 Język C++ a konkurencja ...................................................a................................... 1058 Język C++ a starsze języki programowania...................................................a..... 1058 Język C++ a Visual Basic...................................................a.............................. 1058 Język C++ a C ...................................................a............................................. 1059 Język C++ a Java ...................................................a......................................... 1060 Podsumowanie ...................................................a................................................. 1062 Dodatki Skorowidz 1063 1065 Konstruktory i destruktory — potencjalne problemy Zagadnienia omówione w tym rozdziale: n Więcej o przekazywaniu obiektów poprzez wartość. n Przeciążanie operatorów w klasach nie będących klasrami numerycznymi. n Więcej o konstruowaniu kopii obiektów. n Przeciążenie operatora przypisania. n Rozważania praktyczne — jak chcielibyśmy to zaimplemrentować? n Podsumowanie. Funkcje operatorowe dokonujące przeciążenia operatorów przydają nowego impulsu progra- mowaniu obiektowemu. Okazało się, że oto zamiast koncentrować się na łączeniu w jedną, logicznie powiązaną całość danych i operacji w oparciu o pewne wspólne koncepcje, zaj- mujemy się rozważaniami w kategoriach estetycznych i zagadnieniami równego traktowania wbudowanych, elementarnych typów danych oraz typów definiowanych przez programistę w programach pisanych w C++. Ten rozdział stanowi bezpośrednią kontynuację poprzedniego. W rozdziale 10. „Funkcje ope- ratorowe — jeszcze jeden dobry pomysł” omawiałem zagadnienia odnoszące się do projekto- wania klas typu numerycznego na przykładzie klas QORNGZ (liczba zespolona) oraz 4CVKQPCN (ułamek zwykły). Obiekty stanowiące zmienne (instancje) tych klas są pełnoprawnymi obiek- tami, rzec można z prawdziwego zdarzenia. Stosują się do nich wszystkie zagadnienia od- noszące się do klas i obiektów — deklaracja klasy, kontrola dostępu do składników klasy, projektowanie metod, definiowanie obiektów i przesyłranie komunikatów do obiektów. Typy danych definiowanych przez programistę (klasy) omawiane poprzednio są danymi nume- rycznymi. Nawet jeśli mają wewnętrzną strukturę bardziej skomplikowaną niż elementarne typy liczb całkowitych czy liczb zmiennoprzecinkowych, obriekty takich klas mogą być w kodzie 558 Część II n Programowanie obiektowe w C++ klienta obsługiwane w sposób podobny do liczb całkowitych i liczb zmiennoprzecinkowych. W kodzie klienta obiekty takich typów mogą być dodarwane, mnożone, porównywane itp. Popatrzmy uważnie na sposób wyartykułowania ostatniej myśli (w ostatnich dwóch zdaniach). Określenie „obiekty takich typów mogą…” odnosi się oczywiście do typów zdefiniowanych przez programistę. Co natomiast oznacza „podobny do liczb całkowitych czy liczb zmienno- przecinkowych…”? Skoro te dane porównujemy z typami zdefiniowanymi przez programi- stę, mamy tu na myśli „typy wartości całkowitych i zmiennoprzecinkowych”, a nie same zmienne tychże typów. Lepiej zapewne byłoby tu użyć sformułowania „wbudowane typy danych”. Co oznacza „obiekty takich klas mogą być w kodzie klienta obsługiwane…”? Tu chyba także chodzi o typy zdefiniowane przez programistę? Niezupełnie, ponieważ w tym zdaniu mówi się o obsłudze po stronie kodu klienta. Kod klienta nie obsługuje typów zdefi- niowanych przez programistę, lecz obiekty typu zdefiniowanego przez programistę. To zmien- ne określonego typu (instancje, obiekty) są dodawane, mnożone, porównywane, itp. Autor podkreśla tu wyraźnie ten szczegół, ponieważ wiesz już o klasach i obiektach wystarczają- co dużo, by wyczuwać brak precyzji w niektórych sformułowaniach w dyskusji o programo- waniu obiektowym i by samemu unikać, w miarę możliwości, takich nieprecyzyjnych sfor- mułowań. Innymi słowy, obiekty klas (typów) numerycznych, zdefiniowanych przez programistę, mogą po stronie kodu klienta być obsługiwane podobnie do zmiennych elementarnych typów wbu- dowanych. Z tego powodu obsługa przeciążania operatorów wobec takich klas zdecydowanie ma sens. Zasada C++, by umożliwiać traktowanie zmiennych typów elementarnych i obiek- tów typów zdefiniowanych przez programistę w jednakowy sposób — działa prawidłowo wobec tych klas. W tym rozdziale autor zamierza omówić przeciążanie operatorów wobec takich klas, których obiekty nie mogą być dodawane, mnożone, odejmowane ani dzielone. Na przykład do obsługi łańcuchów znaków w pamięci można utworzyć klasę 5VTKPI. Z ra- cji nienumerycznego charakteru takich klas (z samej ich natury) funkcje operatorowe doko- nujące przeciążenia operatorów wobec tych klas wyglądają sztucznie i nienaturalnie. Na przy- kład możemy dokonać przeciążenia operatora dodawania ( w taki sposób, by umożliwiał konkatenację dwóch obiektów klasy 5VTKPI (dodanie drugiego łańcucha znaków do końca pierwszego) lub np. przeciążenia operatora numerycznej równości ( w taki sposób, by umożliwiał porównanie dwóch łańcuchów znaków reprezentowanych przez obiekty klasy 5VTKPI. I to wygląda dość rozsądnie. Z drugiej jednak strony, trudno wymyślić jakąkolwiek rozsądną interpretację dla operatorów mnożenia czy dzielenia wobec obiektów klasy 5VTKPI. Niemniej jednak funkcje operatorowe dokonujące przeciążania operatorów C++1 dla klas nie- numerycznych są popularne i powinno się wiedzieć, jak z nimi postępować. Ważną różnicą pomiędzy klasami numerycznymi a nienumerycznymi jest to, że w klasach nienumerycznych mogą występować znaczące różnice w objętości danych, którymi mogą posługiwać się obiekty tej samej klasy. Obiekty klas numerycznych zawsze zajmują taką samą ilość miejsca w pamięci. Na przykład obiekty klasy 4CVKQPCN zawierają zawsze dwa pola danych — licznik i mianownik. Natomiast w przypadku klasy 5VTKPI objętość tekstu, który może być przechowywany w po- jedynczym obiekcie tej klasy, może być inna niż objętość tekstu przechowywana w innym obiekcie tej samej klasy. Jeśli klasa rezerwuje dla każdego obiektu taką samą (zbyt dużą) 1 Przypomnijmy: pierwotnie, z natury arytmetycznych —j przyp. tłum. Rozdział 11. n Konstruktory i destruktory — potencjalne problemy 559 ilość pamięci, mamy do czynienia w programie z dwoma niekorzystnymi, a skrajnymi zja- wiskami — marnowaniem pamięci (gdy rzeczywista wielkość tekstu jest mniejsza niż ilość zarezerwowanej pamięci) albo z przepełnieniem pamięci (gdy rzeczywista wielkość tekstu okaże się większa niż ilość zarezerwowanej pamięci). Te dwa niebezpieczeństwa czyhają stale i w którąś z tych dwu pułapek zawsze, prędzej czy później, wpadną ci projektanci klas, któ- rzy rezerwują tę samą ilość pamięci dla każdego takriego obiektu. C++ rozwiązuje ten problem poprzez przyporządkowanie dla każdego obiektu tej samej ilości pamięci (na stercie albo na stosie) zgodnie ze specyfikacją klasy, a następnie ewentualne do- danie, w miarę potrzeby, dodatkowej pamięci na stercie2. Taka dodatkowa ilość pamięci na stercie zmienia się i może być zupełnie inna dla poszczególnych obiektów. Nawet dla jednego, konkretnego obiektu podczas jego życia ta ilość dodatkowej pamięci może się zmieniać. Na przykład jeśli do obiektu klasy 5VTKPI zawierającego jakiś tekst dodawany jest następny łańcuch znaków (konkatenacja), taki obiekt może powiększyć swoją pamięć, by pomieścić nowy, dłuższy tekst. Dynamiczne zarządzanie pamięcią na stercie obejmuje zastosowanie konstruktorów i destruk- torów. Ich nieumiejętne, niezręczne stosowanie może negatywnie wpłynąć na efektywność działania programu. Co gorsza, może to spowodować utratę danych przechowywanych w pamięci i utratę integralności programu, co jest zjawiskiem charakterystycznym dla C++, nieznanym w innych językach programowania. Każdy programista pracujący w C++ powi- nien być świadom tych zagrożeń. To z tego powodu zagadnienia te zostały włączone do tytułu niniejszego rozdziału, mimo że ten rozdział stanowi w istocie kontynuację rozważań o funk- cjach operatorowych dokonujących przeciążenia operatorów. Dla uproszczenia dyskusji niezbędne podstawowe koncepcje zostaną tu wprowadzone w opar- ciu o klasę 4CVKQPCN (o stałej wielkości obiektów), znaną z rozdziału 10. W tym rozdziale te koncepcje zostaną zastosowane w odniesieniu do klasy 5VTKPI z dynamicznym zarządzaniem pamięci na stercie. W rezultacie twoja intuicja programistyczna wzbogaci się o wyczucie relacji pomiędzy instancjami obiektów po stronie kodu klienta. Jak się przekonasz, relacje pomiędzy obiektami okażą się inne niż relacje pomiędzy zmiennymi typów elementarnych, pomimo wysiłków, by takie zmienne i obiekty były traktowane tak samo. Innymi słowy, powinieneś przygotować się na duże niespodzianki. Lepiej nie pomijać materiału zawartego w niniejszym rozdziale. Zagrożenia związane z za- stosowaniem i rolą konstruktorów i destruktorów w C++ są to niebezpieczeństwa zdecydo- wanie realne i należy wiedzieć, jak się przed nimi bronić (broniąc przy okazji swojego szefa i swoich użytkowników). Więcej o przekazywaniu obiektów poprzez wartość Wcześniej, w rozdziale 7. („Programowanie w C++ z zastosowaniem funkcji”) przytaczano argumenty przeciwko przekazywaniu obiektów do funkcji jako parametrów poprzez war- tość albo poprzez wskaźnik do obiektu, natomiast zachęcano, by zamiast tego przekazywać obiekty jako parametry — poprzez referencje. W sposób dynamiczny — przyp. tłum. 2 560 Część II n Programowanie obiektowe w C++ Autor wyjaśniał tam, że przekazanie parametru poprzez referencję jest prawie równie proste, jak przekazanie go poprzez wartość, jest jednakże szybsze — w przypadku tych parametrów wejściowych, które nie zostaną zmodyfikowane przez daną funkcję. Przekazywanie poprzez referencję jest równie szybkie, jak przekazywanie poprzez wskaźnik, ale składnia odnosząca się do parametrów przekazywanych poprzez referencję jest znacznie prostsza — dla parame- trów wyjściowych, które zostają zmodyfikowane przez rdaną funkcję w trakcie jej wykonania. Zaznaczono tam również, że składnia przy przekazywaniu parametrów poprzez referencje jest dokładnie taka sama — i dla parametrów wejściowych, i dla parametrów wyjściowych funkcji. Z tego też powodu autor sugerował stosowanie słowa kluczowego (modyfikatora) EQPUV dla parametrów wejściowych w celu wskazania, że te parametry nie zostaną zmodyfikowane w wyniku wykonania danej funkcji. Jeśli nie stosujemy żadnych takich sugestii, powinno to w sposób nie wzbudzający wątpliwości wskazywać, że te parametry będą zmienione w trak- cie wykonania danej funkcji. Oprócz tego autor przytaczał argumenty przeciwko zwracaniu obiektów z funkcji poprzez wartość, jeśli tylko nie jest to niezbędne w celu przesłania innych komunikatów do takiego zwróconego obiektu (składnia łańcuchowa w wyrażeniach).r Przy takim podejściu przekazywanie parametrów poprzez wartość powinno być ograniczone do przekazywania parametrów wejściowych funkcji, jeśli są one typów elementarnych, i zwrotu z funkcji wartości tychże typów elementarnych. Dlaczego parametry wejściowe typów wbu- dowanych są akceptowalne? Przekazywanie ich poprzez wskaźnik zwiększy stopień złożo- ności i może wprowadzić w błąd osobę czytającą kod, sugerując, że taki parametr może zostać zmodyfikowany podczas wykonania funkcji. Przekazanie ich poprzez referencje (z modyfi- katorem EQPUV) nie jest trudne, ale zwiększa nieco stopień złożoności kodu. Skoro takie pa- rametry są niewielkie, przekazywanie ich poprzez referencje nie zwiększy w najmniejszym stopniu szybkości działania programu. Z wymienionych powodów najprostszy sposób prze- kazywania parametrów (poprzez wartość) jest stosowny dla typów wbudowanych. W trakcie ostatniego rozdziału poznaliśmy wystarczająco techniki programowania, umożli- wiające nam nie tylko omówienie wad i zalet różnych trybów przekazywania parametrów do funkcji i z funkcji, lecz także umożliwiających nam prześledzenie kolejności wywołań funkcji. Oprócz tego przy różnych okazjach autor podkreślał, że inicjowanie i przypisanie, nawet je- śli w obu przypadkach następuje użycie tego samego symbolu  , są różnie traktowane . W tym podrozdziale przy użyciu wydruków komunikatów diagnostycznych zostaną zademonstrowane te różnice. Oba zagadnienia zostaną zademonstrowane za pomocą prrzykładowego kodu z listingu 11.1, zawierającego uproszczoną (i zmodyfikowaną) wersję klasy 4CVKQPCN z poprzedniego rozdziału oraz funkcję testującą — VGUVFTKXGT. Listing 11.1. Przykład przekazania obiektów jako parametrów funkpcji poprzez wartość KPENWFGKQUVTGCOJ ENCUU4CVKQPCN ] NQPIPOTFPORT[YCVPGFCPG XQKFPQTOCNKG RT[YCVPGOGVQF[ Rozdział 11. n Konstruktory i destruktory — potencjalne problemy 561 RWDNKE 4CVKQPCN NQPIPNQPIF MQPUVTWMVQTQIÎNP[MQPYGTULKKFQO[ħNP[ ]POTPFPOF VJKU PQTOCNKG  EQWVQDKGMVWVYQTQP[ MQPUVTWMVQT POTFPOGPFN_ 4CVKQPCN EQPUV4CVKQPCNT MQPUVTWMVQTMQRKWLæE[ ]POTTPOTFPOTFPO EQWVQDKGMVUMQRKQYCP[ MQPUVTWMVQTMQRKWLæE[ POTFPOGPFN _ XQKFQRGTCVQT EQPUV4CVKQPCNT QRGTCVQTRT[RKUCPKC ]POTTPOTFPOTFPO EQWVQDKGMVRT[RKUCP[ QRGTCVQT POTFPOGPFN_ `4CVKQPCN FGUVTWMVQT ]EQWVQDKGMVWUWPKúV[ FGUVTWMVQT POTFPOGPFN_ HTKGPF4CVKQPCNQRGTCVQT  EQPUV4CVKQPCNZEQPUV4CVKQPCN[  XQKFUJQY EQPUV _MQPKGEURGE[HKMCELKMNCU[ XQKF4CVKQPCNUJQY EQPUV ]EQWVPOTFPO_ XQKF4CVKQPCNPQTOCNKG RT[YCVPCOGVQFC ]KH POT ]FPOTGVWTP_ KPVUKIP KH POT ]UKIPPOTPOT_OKGēPCM KH FPO ]UKIPUKIPFPOFPO_D[QD[FYCD[đ[FQFCVPKG NQPIIEFPOTXCNWGFPOPCLYKúMU[YURÎNP[RQFKGNPKM YJKNG XCNWGIEF ]CVT[OCLRQPCNGKGPKWPYR KH IEF XCNWG IEFIEFXCNWGQFGLOWLNKEDúOPKGLUæQFYKúMUGL GNUGXCNWGXCNWGIEF_ POTUKIP  POTIEF FPOFPOIEF_OKCPQYPKMFQFCVPK 4CVKQPCNQRGTCVQT  EQPUV4CVKQPCNZEQPUV4CVKQPCN[ ]TGVWTP4CVKQPCN [POT ZFPO ZPOT [FPO[FPO ZFPO _ KPVOCKP ]4CVKQPCNC  D  E EQWVGPFN EC D CUJQY EQWV DUJQY EQWVEUJQY  EQWVGPFNGPFN TGVWTP _ Spośród wszystkich funkcji odnoszących się uprzednio do klasy 4CVKQPCN pozostawiono tu jedynie funkcje PQTOCNKG , UJQY oraz QRGTCVQT . Poza tym zwróć uwagę, że funkcja dokonująca przeciążenia operatora dodawania, QRGTCVQT , nie jest w tym przypadku me- todą, lecz funkcją zaprzyjaźnioną kategorii HTKGPF. Z tego powodu na początku tego pod- rozdziału (i dalej) w odniesieniu do klasy 4CVKQPCN użyto stwierdzenia: „wszystkich funkcji odnoszących się uprzednio do klasy”, a nie „wszystkich metod należących do klasy”. Autor postąpił tak, choć chciałby jeszcze raz zaakcentować, że zaprzyjaźnione funkcje kategorii HTKGPF z punktu widzenia wszelkich zamiarów i zastosowań są jak metody należące do kla- sy. Funkcja zaprzyjaźniona jest implementowana w tym samym pliku, co wszystkie metody, ma takie same prawa dostępu do prywatnych składników klasy, jak wszystkie metody, jest całkowicie bezużyteczna wobec obiektów klasy innej niż jej klasa „zaprzyjaźniona”, w tym przypadku klasa 4CVKQPCN — jak wszystkie inne metody. Różnica polega jedynie na składni stosowanej przy wywołaniu tej funkcji. Tylko tu funkcja zaprzyjaźniona różni się od metod, 562 Część II n Programowanie obiektowe w C++ ale w przypadku funkcji operatorowych, dokonujących przeciążania operatorów, składnia operatorowa jest dokładnie taka sama dla funkcji zaprzyjaźnionych i dla metod należących do klasy. W obrębie ogólnego (dwuargumentowego) konstruktora klasy 4CVKQPCN dodano wydruk ko- munikatu o charakterze diagnostycznym. Ten wydruk komunikatu powinien następować za każdym razem, gdy obiekt klasy 4CVKQPCN jest tworzony i inicjowany przez ten konstruktor — na początku kodu funkcji OCKP i we wnętrzu kodu funkcji operatorowej QRGTCVQT . 4CVKQPCN4CVKQPCN NQPIPNQPIF YCTVQħEKFQO[ħNPG ] POTPFPOFKPKELQYCPKGFCP[EJ VJKU PQTOCNKG  EQWVQDKGMVWVYQTQP[ MQPUVTWMVQT POTFPOGPFN _ Dodano tu także konstruktor kopiujący z wydrukiem komunikatu diagnostycznego. Ten ko- munikat diagnostyczny zostanie wyprowadzony na ekran zawsze, gdy obiekt klasy 4CVKQPCN będzie inicjowany za pomocą kopiowania pól danych innego obiektu klasy 4CVKQPCN. Takie kopiowanie obiektu na przykład nastąpi wtedy, gdy parametry będą przekazywane poprzez wartość do funkcji QRGTCVQT lub gdy będzie następował zwrot wartości z funkcji (zwrot obiektu poprzez wartość). 4CVKQPCN4CVKQPCN EQPUV4CVKQPCNT MQPUVTWMVQTMQRKWLæE[ ] POTTPOTFPOTFPOMQRKWLRQNCFCP[EJ EQWVQDKGMVUMQRKQYCP[ MQPUVTWMVQTMQRKWLæE[ POTFPOGPFN _ Ten konstruktor kopiujący jest wywoływany, gdy argumenty klasy (typu) 4CVKQPCN są poprzez wartość przekazywane do zaprzyjaźnionej funkcji operatorowej HTKGPFQRGTCVQT . Wbrew mylnemu pierwszemu wrażeniu, ten konstruktor kopiujący nie zostanie wywołany, gdy funk- cja QRGTCVQT będzie zwracać obiekt poprzez wartość, ponieważ przed powrotem z tej funk- cji operatorowej nastąpi wywołanie dwuargumentowego konstruktora ogólnego. W klasie 4CVKQPCN destruktor nie ma do wykonania odpowiedzialnego zadania i został dodany do specyfikacji tej klasy tylko w celu ułatwienia wyprowadzania komunikatów diagnostycz- nych; destruktor zgłosi się poprzez wydruk komunikatu diagnostycznego zawsze, gdy obiekt klasy 4CVKQPCN będzie usuwany. Najciekawszą funkcją jest tu funkcja dokonująca przeciążenia operatora przypisania (). Jej praca polega na kopiowaniu pól danych jednego obiektu klasy 4CVKQPCN na pola danych in- nego obiektu klasy 4CVKQPCN. Czym jej działanie różni się od działania konstruktora kopiu- jącego? W tym stadium możemy stwierdzić, że niczym, choć inny jest typ wartości zwracanej. Konstruktor kopiujący, jak to konstruktor, nie może mieć żadnego typu wartości zwracanej, natomiast metoda operatorowa, jak większość metod, musi mieć jakiś typ wartości zwracanej. Dla uproszczenia przyjęto tu ten typ wartości zwracranej jako XQKF. XQKF4CVKQPCNQRGTCVQT EQPUV4CVKQPCNT QRGTCELCRT[RKUCPKC ] POTTPOTFPOTFPOMQRKQYCPKGFCP[EJ EQWVQDKGMVRT[RKUCP[ QRGTCVQT POTFPOGPFN _ Rozdział 11. n Konstruktory i destruktory — potencjalne problemy 563 Poddany tu przeciążeniu operator przypisania ( jest operatorem dwuargumentowym (bi- narnym). Skąd to wiadomo? Po pierwsze, funkcja operatorowa ma jako jeden parametr obiekt klasy 4CVKQPCN, a nie jest to funkcja zaprzyjaźniona, lecz metoda. Skoro tak, jak każda metoda z jednym parametrem obiektowym, działa na dwóch argumentach. Jednym, niejawnym ar- gumentem jest obiekt docelowy komunikatu (widziany przez metodę jako własny obiekt), dru- gim, jawnym argumentem jest obiekt — parametr. Drugim wyjaśnieniem jest składnia sto- sowania operatora przypisania (po stronie kodu klienta). Operator dwuargumentowy jest zawsze wstawiany pomiędzy pierwszy a drugi operand. Gdy dodaje się dwa operandy, kolejność jest następująca: pierwszy operand, operator, drugi operand (np. C D). Podobnie jest, gdy dokonuje się przypisania. I tu kolejność jest następująca: pierwszy operand, operator, drugi operand (np. C  D). Odnosząc to teraz do składni wywołania funkcji, zauważamy, że obiekt C jest docelowym obiektem komunikatu. W podanej funkcji operatorowej, dokonującej przeciążenia operatora przypisania, pola POT (licznik ułamka) oraz FPO (mianownik ułamka) należą do docelowego obiektu komunikatu, C. Obiekt D jest bieżącym argumentem danego wywołania funkcji operatorowej. W podanej funkcji operatorowej, dokonującej przeciążenia operatora przypisania, pola TPOT oraz TFPO należą do bieżącego argumentu metody, D. Skoro tak, to operator (CD) przypisania odpowiada wywołaniu funkcji operatorowej o na- stępującej składni: CQRGTCVQT D . Ponieważ ta metoda ma t
Pobierz darmowy fragment (pdf)

Gdzie kupić całą publikację:

C++. Inżynieria 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ą: