Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!
Zadejte Vaši e-mailovou adresu:
Kamarád fotí rád?
Přihlas ho k odběru fotomagazínu!
Zadejte e-mailovou adresu kamaráda:
C/C++
Automatické ukazatele v C++
7. března 2002, 00.00 | Dnes si povíme něco o tak zvaném automatickém ukazateli. Automatický ukazatel je šablona třídy,
která "zapouzdřuje" ukazatel na libovolný objekt. Objekt vytvoříme, a dále se již nemusíme starat o jeho dealkoci.
Dnes si povíme něco o tak zvaném automatickém ukazateli. Automatický ukazatel je šablona třídy, která "zapouzdřuje" ukazatel na libovolný objekt. Objekt jednou vytvoříme, zapouzdříme jej v automatickém ukazateli, a již se nemusíme starat o jeho dealokaci. Automatický ukazatel jej odstraní (pomocí delete) automaticky sám ve svém destruktoru.
Automatický ukazatel je šablona z STL. Je deklarována v hlavičkovém souboru memory v prostoru jmen std. Šablona se jmenuje auto_ptr. Má přetížené operátory * a -> tak, aby nám práce s šablonou auto_ptr co nejvíce připomínala práci s obyčejným ukazatelem. Parametrem šablony je typ, na který se bude odkazovat zapouzdřený ukazatel. Pozor parametrem tedy je samotný typ objektu, nikoliv typ ukazatel na objekt. Metody a přetížené operátory (Typ je zde parametr šablony):
- auto_ptr(Typ *pointer = NULL); - konstruktor. Jeho parametr je ukazatel, který chceme zapouzdřit. Nezadáme-li ukazatel, jeho implicitní hodnota je NULL.
- auto_ptr(auto_ptr<Typ> &original); - kopírovací konstruktor. Vytvoří kopii automatického ukazatele. Chování tohoto konstruktoru je asi jiné než by jsme mohli na první pohled čekat. Originální objekt totiž "předá" zapouzdřený ukazatel a sám si "svůj" zapouzdřený ukazatel nastaví na NULL. Obdobně se chová také operátor =. V jednom okamžiku tedy existuje pouze jeden zapouzdřený ukazatel, který si automatické ukazatele nekopírují, ale "předávají".
- ~auto_ptr(); - destruktor. Zlikviduje automatický ukazatel, pokud je v automatickém ukazateli zapouzdřen ukazatel na jiný objekt, dojde k likvidaci tohoto objektu pomocí delete.
- operator=(auto_ptr<Typ> &original); - obdobné chování jako kopírovací konstruktor. Originál předá, nikoliv zkopíruje zapouzdřený ukazatel.
- Typ &operator* () const; - vrátí referenci na objekt, na který se odkazuje zapouzdřený ukazatel.
- Typ *get() const; - vrátí zapouzdřený ukazatel.
- X *operator-> () const; - umožní přístup k prvkům objektu, na který se odkazuje zapouzdřený ukazatel. V podstatě také vrací zapouzdřený ukazatel jako get(), ale v případě, že budeme přistupovat k prvkům objektu, nabízí přehlednější zápis.
- void reset(Typ *pointer = NULL); - nastaví zapouzdření nového ukazatele. Objekt, na který se odkazoval starý ukazatel bude zlikvidován operátorem delete. Místo něj bude nyní nastaven nový zadaný ukazatel. Metoda reset vlastně přenastaví zapouzdřený ukazatel. Implicitní hodnota nového ukazatele je NULL.
- X *release(); - vrátí zapouzdřený ukazatel. Zapouzdřený ukazatel bude nyní NULL. Objekt, na který se odkazoval "starý" ukazatel, který je vrácen, nezlikviduje. Metoda v podstatě slouží k "vysvobození" zapouzdřeného ukazatele. Použijeme ji tehdy, jestliže chceme, aby se automatický ukazatel přestal starat o náš normální ukazatel.
Vše si uvedeme na jednoduchém příkladě. Vytvoříme instanci naší pokusné třídy. Ukazatel na ni předáme automatickému ukazateli jménem a. Ukážeme si jak zavolat metodu pomocí operátoru ->. Potom vytvoříme automatický ukazatel b, který bude "kopie" a. Až skončí aktuální blok, automatický ukazatel b bude zlikvidován. S ním bude také zlikvidován objekt, na který se odkazoval zapouzdřený ukazatel. Když jsme vytvářeli b, přepsali jsme zapouzdřený ukazatel v a na NULL. O všem se přesvědčíte, jestliže program spustíte.
|
Já osobně automatickými ukazateli nejsem příliš nadšen, a nepoužívám je. Původně jsem se o nich nechtěl ani zmiňovat. Je ale dobré vědět, že existují. Hlavně jsem tento článek napsal jako úvod k mému příštímu článku.
Na automatických ukazatelích mi nejvíce vadí, že při jejich kopírování si zapouzdřený ukazatel pouze předávají. Daleko lepší by bylo, kdyby ukazatele kopírovali. Objekt by byl pouze jeden, na který by se odkazovalo více ukazatelů. Každý z těchto ukazatelů by byl zapouzdřen v automatickém ukazateli. Bylo by to krásné do té doby, než by jeden z automatických ukazatelů byl zlikvidován. Ve svém destruktoru by totiž dealokoval onen objekt. Ostatní ukazatele by se odkazovali do nealokované paměti. Kdyby ale někde existovala informace o tom, kolik takových ukazatelů se na objekt odkazuje, mohl by být objekt zničen až v době, kdy na něj neexistuje ukazatel. Tím by jsme udělali něco skvělého. Vytvořili by jsme objekt, se kterým by jsme pracovali pomocí našich "inteligentních" ukazatelů. O likvidaci tohoto objektu by jsme se již nestarali. Objekt by byl sám zlikvidován v momentě, kdy by na něj již neexistoval žádný odkaz. Myslíte, že něco takového v C++ nejde? V příštím článku něco takového uděláme.
Obsah seriálu (více o seriálu):
- Základy OOP v C++: Od C k C++
- Základní pojmy objektově orientovaného programování
- Vytváření tříd, instance třídy, zasílání zpráv v C++
- Vytváření instancí - konstruktory, destruktory
- Kopírovací konstruktor v C++
- Jednoduchá dědičnost v C++
- Časná versus pozdní vazba - úvod do polymorfismu v C++
- Polymorfismus - dokončení
- Vícenásobná dědičnost v C++
- Vícenásobná dědičnost v C++ - opakovaná dědičnost
- Vícenásobná dědičnost v C++ - volání konstruktorů a destruktorů
- Přetěžování operátorů v C++ 1.díl
- Přetěžování operátorů v C++ 2. díl
- Vstupní a výstupní operace pomocí datových proudů v C++
- Přetěžování operátorů << a >> pro datové proudy v C++
- Neformátovaný vstup a výstup v C++
- Paměťové proudy v C++
- Prostory jmen v C++
- Řetězce v C++
- Výjimky v C++
- Výjimky v C++ - výjimky tvoří dědičnou hierarchii
- Výjimky v C++ - dokončení
- Dynamická identifikace typů v C++
- Přetypování v C++
- Problémy s typy při vícenásobné dědičnosti
- Šablony funkcí v C++
- Šablony datových typů v C++
- Vnitřní typy u parametrů šablon, vnořené šablony v C++
- Pole s libovolným intervalem indexování v C++
- Datové kontejnery v C++ - Úvod do STL
- Vector - datový kontejner v C++
- Iterátory v C++
- Šablona vector v C++ a iterátory
- Asociativní pole v C++
- Množina v C++
- Funkční objekty v C++
- Standardní funkční objekty v C++
- Úvod do standardních algoritmů v C++
- Kopírovací a přesouvací algoritmy v C++
- Vyhledávací algoritmy v C++
- Skenovací (prohlížecí) algoritmy v C++
- Transformační algoritmy v C++
- Řadící algoritmy v C++
- Halda v C++
- Standardní algoritmy v C++ - dokončení
- Automatické ukazatele v C++
- Inteligentní ukazatel - čítač referencí v C++
- Použití čítače referencí v C++
- Kopírování velkých objektů v C++
- Řízené kopírování prvků v poli v C++
- Dokončení seriálu objektově orientované programování v C++
-
25. listopadu 2012
-
30. srpna 2002
-
10. října 2002
-
4. listopadu 2002
-
12. září 2002
-
25. listopadu 2012
-
28. července 1998
-
31. července 1998
-
28. srpna 1998
-
6. prosince 2000
-
27. prosince 2007
-
4. května 2007