c++.-kanony-wiedzy-programistycznej cała książka.pdf

(3239 KB) Pobierz
4
Spis treści
Zagadnienie 21. Przeciążanie to nie to samo co przesłanianie ............................ 89
Zagadnienie 22. Wzorzec Template Method ......................................................... 91
Zagadnienie 23. Przestrzenie nazw .................................................................... 93
Zagadnienie 24. Wyszukiwanie metod ................................................................ 97
Zagadnienie 25. Wyszukiwanie ADL ................................................................... 99
Zagadnienie 26. Wyszukiwanie funkcji operatorów ........................................... 101
Zagadnienie 27. Odpytywanie klasy ................................................................. 103
Zagadnienie 28. Semantyka porównywania wskaźników ................................... 107
Zagadnienie 29. Konstruktory wirtualne i wzorzec Prototype ............................ 109
Zagadnienie 30. Wzorzec Factory Method ........................................................ 113
Zagadnienie 31. Kowariancja typów zwracanych .............................................. 117
Zagadnienie 32. Blokowanie kopiowania .......................................................... 121
Zagadnienie 33. Wytwarzanie abstrakcyjnych klas bazowych ............................ 123
Zagadnienie 34. Blokowanie przydziału na stercie ............................................ 125
Zagadnienie 35. Miejscowa wersja new ........................................................... 127
Zagadnienie 36. Zarządzanie pamięcią w klasie ............................................... 131
Zagadnienie 37. Przydział tablicowy ................................................................. 135
Zagadnienie 38. Aksjomaty odporności na wyjątki ........................................... 139
Zagadnienie 39. Funkcje odporne na wyjątki .................................................... 143
Zagadnienie 40. Reguła RAII ........................................................................... 147
Zagadnienie 41. Operator new, konstruktory i wyjątki ...................................... 151
Zagadnienie 42. Inteligentne wskaźniki ........................................................... 153
Zagadnienie 43. Niezwykłości auto_ptr ............................................................ 155
Zagadnienie 44. Arytmetyka wskaźników ......................................................... 157
Zagadnienie 45. Terminologia szablonów ......................................................... 161
Zagadnienie 46. Jawna specjalizacja szablonu klasy ......................................... 163
Zagadnienie 47. Częściowa specjalizacja szablonu ........................................... 167
Zagadnienie 48. Specjalizacja metody szablonu klasy ....................................... 171
Zagadnienie 49. Niepewność co do nazw typów ............................................... 175
Zagadnienie 50. Szablony składowych ............................................................. 179
Zagadnienie 51. Niepewność co do nazw szablonów ......................................... 183
Zagadnienie 52. Specjalizacja dla informacji o typie ......................................... 185
Spis treści
5
Zagadnienie 53. Osadzanie informacji o typie ................................................... 189
Zagadnienie 54. Klasy cech ............................................................................. 193
Zagadnienie 55. Szablony parametrów szablonu ............................................... 199
Zagadnienie 56. Klasy wytycznych ................................................................... 205
Zagadnienie 57. Dedukcja argumentów szablonu .............................................. 209
Zagadnienie 58. Przeciążanie szablonów funkcji ............................................... 213
Zagadnienie 59. Reguła SFINAE ...................................................................... 217
Zagadnienie 60. Algorytmy uogólnione ............................................................. 221
Zagadnienie 61. Konkretyzuje się tylko to, co używane .................................... 225
Zagadnienie 62. Bariery #include ..................................................................... 229
Zagadnienie 63. Opcjonalne słowa kluczowe .................................................... 231
Bibliografia ............................................................................ 235
Skorowidz .............................................................................. 237
Zagadnienie 7.
Wskaźniki const
i wskaźniki na const
W swobodnych konwersacjach programiści C++ często mówiąc „wskaźnik
const
mają tak naprawdę na myśli „wskaźnik na
const
”. Szkoda, bo to dwa różne pojęcia.
T *pt = new T;
const T *pct = pt;
T *const cpt = pt;
//
wskaźnik na T
//
wskaźnik na const T
//
wskaźnik const na T
Zanim zaczniemy gorączkowo tasować
const
w deklaracjach wskaźników, powinni-
śmy
najpierw zdecydować, o co nam chodzi. Co ma być stałe: wskaźnik, obiekt
wskazywany, czy może oba? W deklaracji
pct
wskaźnik nie jest stały, stały (niemo-
dyfikowalny) ma być za to obiekt przezeń wskazywany; kwalifikator
const
modyfikuje
typ bazowy
T
, a nie modyfikator wskaźnika
*
. W przypadku
cpt
deklarowany jest
niemodyfikowalny (stały) wskaźnik obiektu modyfikowalnego; kwalifikator
const
modyfikuje tu modyfikator wskaźnika
*
, zostawiając w spokoju typ bazowy
T
.
Aby jeszcze zaciemnić składnię wskaźników i kwalifikatora
const
, można powiedzieć,
że
kolejność specyfikatorów deklaracji, czyli kolejność tego, co występuje w deklara-
cji wskaźnika przed pierwszym modyfikatorem
*
, jest nieistotna. Na przykład, obie
poniższe deklaracje wprowadzają do programu zmienne dokładnie tego samego typu:
const T *p1;
T const *p2;
//
wskaźnik na const T
//
również wskaźnik na const T
Pierwsza postać jest bardziej klasyczna, ale wielu ekspertów C++ zaleca teraz stoso-
wanie postaci drugiej. W uzasadnieniu podnoszą,
że
owa postać zmniejsza ryzyko
nieporozumień, bo można sobie pomóc odczytaniem deklaracji od tyłu: „wskaźnik na
const T
”. Wybór jednej z powyższych form jest dowolny, ważne, aby trzymać się raz
przyjętej konwencji. Słowem, należy uważać na częsty błąd mylenia deklaracji wskaź-
nika stałego z deklaracją wskaźnika na obiekt stały (niemodyfikowalny).
T const * p3;
T *const p4 = pt;
//
wskaźnik na obiekt stały
//
stały wskaźnik na obiekt modyfikowalny
22
Zagadnienie 7. Wskaźniki const i wskaźniki na const
Możliwe jest oczywiście zadeklarowanie również stałego (
const
) wskaźnika na obiekt
stały (
const
):
const T * const cpct1 = pt;
//
wszystko const
T const * const cpct2 - cpct1; //
identyczny typ
Zauważmy,
że
często zamiast wskaźnika
const
, prościej zastosować referencję:
const T &rct = *pt;
T &rt = *pt;
//
zamiast const T * const
//
zamiast T *const
W niektórych z powyższych przykładów mieliśmy możliwość konwersji wskaźnika
bez
const
(modyfikowalnego) na wskaźnik
const
(niemodyfikowalny). Możemy na
przykład zainicjalizować
pct
(typu
const T *
) wartością
pt
(typu
T *
). Jest to do-
zwolone, ponieważ — mówiąc potocznie — nie grozi to niczym złym. Sprawdźmy,
co stanie się w wyniku skopiowania adresu obiektu modyfikowalnego do wskaźnika
na obiekt niemodyfikowalny (rysunek 7.1).
Rysunek 7.1.
Wskaźnik na const
może wskazywać
obiekt
modyfikowalny
(bez const)
Wskaźnik
pct
(wskaźnik na
const
) wskazuje obiekt typu
T
niebędący stałym (bez
const
), ale nie wprowadza to
żadnej
sprzeczności. W rzeczy samej, sytuacja odwoły-
wania się do obiektów modyfikowalnych za pośrednictwem wskaźników na
const
jest
dość częsta:
void aFunc( const T *arg1, const T &arg2 );
//
T *a = new T;
T b;
aFunc( a, b );
Przy wywołaniu
aFunc
następuje inicjalizacja
arg1
adresem
a
i
arg2
adresem
b
. Nie
sposób jednak powiedzieć, czy
a
faktycznie wskazuje obiekt niemodyfikowalny, albo
czy
b
jest
const
; zakładamy jedynie,
że
tak będą traktowane w obrębie funkcji
aFunc
.
To bardzo użyteczne.
Konwersja odwrotna, czyli ze wskaźnika na obiekt niemodyfikowalny do postaci
wskaźnika na obiekt modyfikowalny nie jest dozwolona, bo byłaby niebezpieczna
(patrz rysunek 7.2).
Rysunek 7.2.
Wskaźnik na obiekt
bez const nie może
odnosić się do
obiektu const
Zgłoś jeśli naruszono regulamin