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++
Řízené kopírování prvků v poli v C++
cpp oop
13. června 2002, 00.00 | Dnes dokončíme téma řízené kopírování objektů v C++. Podíváme se na řízené kopírování prvků pole. Vytvoříme si šablonu pole, které bude kopírovat své prvky jen v případě, že to bude potřeba. Šablona je v článku k dispozici ke stažení.
V minulém článku jsme se seznámili se způsobem řízení kopírování velkých objektů. Uvedli jsme si jednu velkou nevýhodu celé techniky. Obecně ji nelze nijak parametrizovat. Velice často ale nastává případ, že objekt je veliký, protože jeho atributem je veliké pole. Taková byla i situace v ukázkovém příkladě v minulém článku . Takový speciální případ parametrizovat lze. Nejprve ale všem, kteří můj minulý článek "Kopírování velkých objektů v C++" nečetli, doporučuji jej přečíst. V tomto článku budu na předchozí článek navazovat.
Představme si velké pole. Podle návodu uvedeného v minulém článku jej rozdělíme na dvě části. Na část "obsahovou" a "přístupovou". Přístupovou část můžeme nazývat také "prezentační". Při kopírování pole vytvoříme pouze plytkou kopii. Pokud budeme z plytké kopie pouze číst, není důvod vytvářet hlubokou kopii. Hluboká kopie se vytvoří automaticky až při zápisu do prvku pole. Pro jednoduchost budeme při zápisu do jednoho prvku pole v případě potřeby vždy kopírovat celé pole, nejen daný prvek. O výhodách a nevýhodách si povíme v závěru.
Mohli by jsme si takhle vytvořit pole prvků nějakého typu. Poté jiné pole prvků jiného typu. Je zřejmé, že všechny třídy si budou podobné. Budou se lišit pouze typem uložených prvků. Jak asi mnohé napadne, vhodným řešením je šablona. Šablona se napíše jednou a podle potřeby se budou vytvářet její instance - třídy.
Nejprve vytvoříme šablonu obsahových tříd. Nazveme ji __Atribut. Šablona přístupových tříd se bude jmenovat Atribut. To proto, že instance šablony bude typ, jehož objekty budou atributy jiných tříd. Například v minulém článku jsme měli třídu s atributem pole typu int. Atribut možná není nejvhodnější název, ale mne žádný jiný nenapadl. Šablona __Atribut bude podle rad z minulého článku obsahovat čítač referencí, samotná data (pole) a délku pole. Dále metody, které manipulují s čítačem referencí, metody vracející ukazatel na první prvek v poli, konstruktory a destruktor.
|
Parametrem šablony je typ prvků, které budou v poli uloženy.
Přistupme k implementaci šablony přístupových tříd.
|
Šablona třídy je v principu stejná jako přístupová třída z minulého článku. Obdobným způsobem zvyšuje a snižuje počet referencí. Soukromá metoda copy je zavolána vždy, je-li potřeba vytvořit kopii. Tedy jestliže je prováděna operace, která by změnila hodnotu nějakého prvku v poli. Naopak metoda free je zavolána v případě, že přístupový objekt "zahazuje" referenci na "obsahový" objekt.
Metoda at slouží k získání prvku v poli. Metoda at vrací samotný prvek, nikoliv referenci na něj. Proto by měla být použita jen na levé straně výrazu. Oproti operátoru [] neprovádí hlubokou kopii. Při použití operátoru [] (vrací referenci) je nutné provést hlubokou kopii. Nevíme totiž, jestli bude použit na pravé, či levé straně výrazu. Pod pojmy "na pravé straně výrazu" a "na levé straně výrazu" mám na mysli to, jestli je ve výrazu něco napravo nebo nalevo od operátoru =. Například a = b; je a na levé straně výrazu a b na pravé straně výrazu.
Kompletní implementace šablony třídy Atribut a __Atribut jsou v souboru atribut.h. Šablona je opět deklarovaná v prostoru jmen www_builder_cz.
Nyní si vytvoříme jednoduchý příklad použití šablony Atribut. Bude se jednat o matici, která bude mít řízené kopírování svých prvků. Bude kopírován pouze řádek, ve kterém došlo ke změně. Matice může mít mnoho prvků. Kopírovat se ale bude jen několik řádků, podle toho jaké prvky budeme měnit. Při velmi velkých rozměrech matice to bude výhodné. Ještě než se podíváme na zdrojový text třídy Matice, musíme si ujasnit, že šablona Atribut (resp. __Atribut) má jako svůj parametr typ , který má k dispozici bezparametrický konstruktor, kopírovací konstruktor a operátor =.
Kromě matice vytvoříme funkce vypis a fce. Funkce vypis vypíše prvky matice. Je dobré si všimnout, že matice předávaná této funkci jako parametr nebude vlastně nikdy kopírována. Při předávání parametru dojde k vytvoření pouze mělké kopie. Druhá funkce fce je ukázková a asi nemá žádné využití. Vynuluje zadaný řádek a ve vzniklé matici sečte zadaný sloupec.
|