Cvičení č. 2 - Gumové pole

K výstupu na obrazovku (standardní výstup) se v C++ používá třída cout definovaná v hlavičkovém souboru iostream. Je to standardní soubor otevřený pro zápis. Protože ale souborové operace v C++ budeme cvičit až mnohem později, zatím si jen řekneme, že k zobrazení dané proměnné i stačí využít přetíženého operátoru <<, např. cout << i;. To lze také skládat: cout << "Ahoj " << i << endl;. Speciální identifikátor endl odřádkuje. Více později, bude toho až Vás hlava rozbolí.

C++ má kvůli rozsáhným projektům tzv. namespace, ve kterém se definují jednotlivé identifikátory. Příslušný namespace se pak musí uvádět před identifikátorem, např. std::cout. Abychom si ale ušetřili práci, konstrukcí using namespace std řekneme překladači, že se do std má podívat vždy.

Všimněte si, že hlavičkové soubory v C++ již nemají žádnou koncovku. K těm standardním ale stále ještě existují i .h verze. Pro úplnost nutno dodat, že nejsou úplně stejné - při použití .h nemusíte uvádět namespace.

Úkol č.1

Naprogramujte třídu reprezentující seznam položek typu int.

Třída bude obsahovat funkci push_back pro přidávání prvku na konec seznamu, push_front pro přidávání prvku na začátek, delete pro odstraňování prvků a print, která zobrazí hodnotu prvku na obrazovku.

Seznam lze samozřejmě implementovat mnohými způsoby.

Destruktor seznam odalokuje.

Metody definované přímo v hlavičce třídy jsou inline, a tedy se její kód přímo přikládá na místo použití. To má výhodu především u velmi malých metod a tříd reprezentujících data. Přináší ale nevýhodu v propagaci střev metod směrem k uživateli.

Odsazovat v blocích public, protected a private? To záleží. Pro třídy s velkým množstvím položek doporučuji odsazovat, u malých tříd dle přehlednosti.

Kdy mají být metody označené jako const? Když nemění stav objektu - to je ale trochu obšírnější termín. Z hlediska jazyka se v takové metodě chovají atributy třídy jako by byly const. Přitom ale objekty, na které tyto atributy ukazují, již const nejsou. A to je sémanticky špatně u takových objektů, jako náš seznam. Pro náš příklad - print() bude const, ale insert() již const nebude, a to i kdyby se v ní nezměnil žádný atribut. Stojí za upozornění, že u const parametrů lze volat pouze const metody.

Dobrá rada č.1

Metody, které nemají měnit stav objektu, vždy označte jako const.

Máte právo libovolně omezovat vytváření instancí objektů - deklarujte konstruktor v sekci private nebo protected dle potřeby. To ale neplatí pro destruktor (pročpak asi?). Někdy se hodí deklarovat kopírovací konstruktor v sekci private, např. k zákazu předávání hodnotou (známe z programovacího jazyka Java).

Dobrá rada č.2

Snažte se přístup k atributům a metodám maximálně omezit tak, aby to odpovídalo jejich předpokládanému použití.

Úkol č.2

Implementujte kopírovací konstruktor.

Co dělá implicitní kopírovací konstruktor? Proč je to špatně?

Dobrá rada č.3

Když vytváříte třídu, jejíž stav bude uložen v jiných objektech, vždy definujte kopírovací konstruktor.

Úkol č.3

Implementujte iterátor.