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++
Šablona vector v C++ a iterátory
2. listopadu 2001, 00.00 | Dříve jsme zabývali šablonou vector. Neukázali jsme si ale metody insert a erase. Těmto metodám se dnes budeme věnovat. Ukážeme si jak efektivně kopírovat do kontejneru pole. A jak do kontejnereru ukládat objekty, které pro ukládání nesplńují podmínky.
V předminulém článku jsme se zabývali šablonou vector. Neukázali jsme si ale metody insert a erase. Právě těmto metodám se dnes budeme věnovat. Také si ukážeme jak efektivně nakopírovat do kontejneru obyčejné pole, nebo obsah jiného kontejneru. A jak přimět kontejner aby pracoval i s instancemi tříd, které nesplňují podmínky pro uložení v kontejneru.
Metoda insert
Metoda insert slouží k vkládání prvků do vektoru. V žádném případě se nejedná o nějakou obdobu operátoru [], nebo metody at. Metoda insert žádný prvek vektoru nepřepíše. Vkládání prvku pomocí insert vypadá tak, že všechny prvky od pozice na kterou chci zapisovat až po konec se posunou "doprava", tedy jejich index bude zvýšen o 1. Poté se nový prvek zapíše na novou pozici. Vektor se při této operaci zvětší o jeden prvek. Kdybychom chtěli něco takového provést v poli, museli by jsme velikost pole zvětšit (nejspíše pomocí realloc), poté překopírovat část prvků na nové pozice, a nakonec zapsat nový prvek. V kontejneru vector je všechna tato činnost již naprogramovaná a ukrytá v metodě insert. Metoda insert je 3 krát přetížena (existují 3 varianty této metody).
Metoda erase
Oproti metodě insert metoda erase prvky z kontejneru odebírá. Existují dvě varianty:
Další věc, o které bych se chtěl v souvislosti s vektorem zmínit je konstruktor, který má dva parametry - vstupní iterátory. Tento konstruktor vytvoří vektor, který bude obsahovat kopie prvků mezi zadanými iterátory jiného kontejneru. Často se tento konstruktor používá pro vytvoření vektoru z obyčejného pole. Vše si podrobně ukážeme v příkladě.
|
Kontejner a typ prvků, který neodpovídá podmínkám pro vkládání do kontejneru
Ve svém článku Datové kontejnery v C++ - Úvod do STL jsem uvedl podmínky pro typ, jehož instance chceme do kontejneru ukládat. Právě u metod insert a erase vidíme, proč je u vkládaného objektu důležitá schopnost sebe kopírovat. Mnohdy ale můžeme pracovat s třídou, která nemá kopírovací konstruktor, resp. operátor = přetížen a implicitní použít nelze. Viz můj článek Kopírovací konstruktor v C++. Také je možné, že kopírovací konstruktor, či operátor = je deklarován jako soukromá položka. Tím autor třídy dal jasně najevo, že kopírování instancí je zakázáno. Jak pracovat s takovými typy v kontejnerech? Řešení ukážu na kontejneru vector, protože ten již známe. Tento postup je ale použitelný pro libovolný kontejner.
Celá finta spočívá v tom, že do kontejneru nebudeme ukládat samotné prvky, ale pouze ukazatele na ně. Vytvoříme si ukázkovou třídu, která nesplňuje podmínky pro to, aby její instance byly ukládány do kontejneru.
|
U této třídy nelze korektně použít implicitní kopírovací konstruktor ani operátor= - povede to k pádu programu. Také si můžete vyzkoušet, že k nekorektnímu chování dojde i tehdy, jsou-li instance této třídy vkládány, či odebírány z libovolného kontejneru.
Kontejner ukazatelůUkazatel vždy splňuje podmínky pro uložení v kontejneru. Můžeme vytvořit kontejner ukazatelů, musíme mít ale neustále na mysli dvě věci. Jednak nesmíme do kontejneru uložit ukazatel na lokální objekt (lokální zásobník). Všechny objekty, na které ukazující ukazatelé budou v nějakém kontejneru by měly být vytvořeny pomocí new. Dále si také musíme uvědomit, že při likvidaci kontejneru (volání jeho destruktoru) budou zlikvidovány jeho prvky - ukazatele, nebudou ale zlikvidovány samotné objekty, na které bylo z kontejneru odkazováno. O zavolání jejich destruktorů se musíme postarat sami. Například:
|
Tolik tedy k vektoru. V mnoha případech je použití vektoru pohodlnější, než použití pole. Program pracující s vektorem je sice trochu pomalejší (oproti programu pracujícím s polem), ale velkého zpoždění se bát nemusíme. Žádná metoda žádného kontejneru není volána pozdní vazbou, a některé jsou dokonce překládány jako inline. Také je fakt, že kontejnery jsou šablony, tedy značná část operací se provede již v době kompilace, při běhu programu se na rychlosti nijak neprojeví. Příště se podíváme na kontejnery map a multimap, což jsou asociativní pole.
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