Życie pisze najbardziej oryginalne, najbardziej komiczne, a jednocześnie najbardziej dramatyczne scenariusze.

To tyle. Jeśli masz jeszcze jakieś pytania, to najlepiej od razu dodam, że jeszcze ani raz w żadnym poważnym programie nie użyłem zagnieżdżenia definicji klas. 13.1 Lokalna definicja klasy Tutaj mówić będziemy o zagnieżdżeniu definicji klasy, ale nie w innej klasie, tylko w jakiejś funkcji. Jeśli definicję klasy umieścimy w funkcji, to ma ona zakres ważności lokalny, ograniczony do bloku tej funkcji. Podkreślam: wewnątrz funkcji jest definicja klasy, a nie konkretny egzemplarz jej obiektu. Nazwa takiej klasy widziana jest tylko w zakresie, w którym jest zdefiniowana, czyli poza zakresem tej funkcji nie da się kreować obiektów tej klasy, ani nawet na nich działać. Funkcje składowe takiej klasy muszą być zdefiniowane wewnątrz ciała klasy (będą więc inline). Nie można definicji tych funkcji umieścić poza ciałem klasy bo: *»* - zaraz za definicją klasy, (czyli jeszcze w funkcji, w której jest ona lokalną) nie można, bo łamałoby to wspomnianą już w poprzednim paragrafie zasadę C++, że definicje funkcji nie mogą być zagnieżdżane w innych funkcjach, *#* - definicji funkcji składowych tej lokalnej klasy nie można umieścić w zakresie globalnym, bo tam nazwa tej klasy jest zupełnie nieznana. Z tych ograniczeń wynika następująca zasada praktyczna: Skoro funkcje składowe będą inline - to powinny być krótkie. 332 Rozdz. 13 Zagnieżdżona definicja klasy Lokalna definicja klasy Klasa lokalna przydaje się wtedy, gdy mamy do czynienia z klasą bardzo prostą i gdy jej użycie ogranicza się tylko do wnętrza tej jednej jedynej funkcji w programie. Lokalna klasa ma zakres ważności wnętrza funkcji, w której się znajduje, więc może używać zdefiniowanych w niej nazw typów (typedef), typów wylicze- niowych (enum), zdefiniowanych w niej zmiennych statycznych, a także na/w zadeklarowanych w niej jako extern. Strasznie to zawiłe, co? Nie przejmuj się, łatwo to zapamiętać tak: W klasie tej można używać tego wszystkiego, co już istnieje w czasie kompilacji oraz linkowania. • Definicje typów wyliczeniowych (enum) wtedy już istnieją? Tak, są przecież napisane czarno na białym. • Instrukcje typedef? - także - kompilator je poznał. • Nazwy zdeklarowane jako typu extern? Także - kompilator się z nimi zapoznał i w czasie linkowania już będzie dokładnie wiadomo, które komórki w pamięci one zajmą. Skoro tak, to czego nie ma w tym zestawie ? Zmiennych (obiektów) automatycznych, które najczęściej definiujemy sobie w funkcjach. One będą bowiem leżały na stosie, więc ich adres jest na etapie kompilacji i linkowania jest nawet w przybliżeniu nieznany. Spójrz na stos książek na Twoim biurku - jego wygląd zależy nie tylko od tego, co robisz teraz, ale także od tego, co robiłeś wczoraj i przedwczoraj. Kompilator nie może więc wygenerować dla naszej klasy lokalnej kodu, który sprawi, że zmienną z tej komórki stosu doda się do tamtej, a rezultat złoży się w jeszcze innej. Zatem: I Klasa lokalna w funkcji - nie może używać jej zmiennych auto- matycznych Ciekawostki o zasłanianiu Jeszcze jedna ciekawa rzecz: Jeśli mamy zmienną globalną o nazwie xyz, a w funkcji zdefiniujemy sobie zmienną automatyczną o takiej samej nazwie xyz, to zwykle nazwa zmiennej lokalnej automatycznej zasłania nazwę glo- balną. Tutaj jednak, w wypadku klasy lokalnej, znowu jest inaczej. Gdy kompilator pracuje nad definicją lokalnej klasy - nie da się nawet w przybliżeniu określić wyglądu stosu - zatem kompilator daje to, co może: obiekt globalny. On nie jest dla klasy lokalnej zasłonięty obiektem automatycznym. Jakiekolwiek odnie- sienie się od obiektu xyz będzie odniesieniem się do globalnego obiektu xyz. Próba odniesienia się do jakiejś nazwy, która jest tylko lokalna, uznana zostanie za błąd w czasie kompilacji. I jeszcze jedno: lokalna klasa nie może mieć swoich składników statycznych. Rozdz. 13 Zagnieżdżona definicja klasy 333 Lokalna definicja klasy Pokażmy to wszystko na przykładzie #include