Využití šablon - template


Realizujte strukturu vektor pomocí mechanizmu template/šablon. Toto řešení zajistí tvorbu vektoru pro různe datové typy z jednoho zdrojového textu vytvořeného pro obecný datový typ. Strukturu realizujte na základě následujícího návodu a tak, aby fungovala dodaná funkce main. Na základě tvoření kódu pro strukturu TVector postupně uvolňujte překlad příslušné části funkce main přesunem příkazů podmíněného překladu #if 0 … #endif (v některých fázích vývoje bude nutné použít více sekcí podmíněného překladu).


  1. Pro předávání parametrů používejte přednostně reference a následně hodnoty.

  2. Vytvořte projekt se třemi soubory: main.cpp (do něj překopírujte dodaný kód) s funkcí main, hlavičkový soubor vektor.h s definicemi typů a šablon, zdrojový soubor vektor.cpp pro ty části kódu pro vektor, které nemohou být v hlavičkovém souboru. Hlavičkový soubor standardně ošetřete a vložte (include) do obou zdrojových souborů.
    Pro kontrolu paměti přidejte soubory knihovny check: check.cpp a check.h. Knihovna check.h bude includována jako poslední v hlavičkovém souboru vektor.h. Hlavičkový soubor potom bude includován jako poslední soubor ve zdrojových souborech (tím se splní podmínka, že check.h je posledním includovaným souborem).

  3. Nadefinujte strukturu pro typ TVector pomocí template. Proměnné pro členská data budou iData, iSize (počet uložených prvků) a iCapacity (dostupné místo pro uložení prvků). Typ šablony nastavte implicitně na double. Proveďte implicitní nastavení členských dat na nulové hodnoty.

  4. Ve funkci main (v bloku try) definujte proměnné i1,i2,i3 jako proměnné struktury TVector pro typ int a d1,d2,d3 pro struktury TVector pro typ double. Některé proměnné inicializujte v definici na nulové hodnoty. Ověřte, že ostatní hodnoty jsou inicializované díky inicializaci prvků struktury (v její definici).

  5. Pomocí výčtového typu enum vytvořte typ pro chybová hlášení. Tento typ nazvěte TError. Bude nabývat hodnot : EOk = 0, EWrongSize, ENoMemory, ENotAllocated, EAlreadyAllocated, EInvalidParameter. Pomocí následujícího kódu vytvořte ve zdrojovém souboru řetězce příslušné k chybovým kódům TError. V hlavičkovém souboru zajistěte zveřejnění této proměnné.
    #define TOSTR(a) (#a)
    const char *ErrorStr[] = { TOSTR(EOk), TOSTR(EWrongSize), TOSTR(ENoMemory), TOSTR(ENotAllocated), TOSTR(EAlreadyAllocated), TOSTR(EInvalidParameter) };

    Následující kód pište do bloku try, za kterým budete odchytávat výjimky typu TError a tisknout jejich název. V případě odchycení jiné výjimky vypište hlášení, že došlo k neočekávané výjimce.

  6. Napište inline funkci IntegrityCheck, která bude mít jako parametr strukturu a vrací bool značící, že iData, iSize a iCapacity si odpovídají. (iSize<=iCapacity, je-li iData nebo iCapacity vynulováno, potom je nula i v ostatních proměnných).
    Tuto funkci dále volejte ve funkcích na všechny argumenty typu TVector, v okamžicích, kdy je nutné kontrolovat integritu/správnost struktury – tj. otestovat, že uživatel neporušil špatnou manipulací základní logiku/návaznost proměnných uvnitř struktury.

  7. Napište funkci Allocate (s parametry reference na TVector, parametrem pro požadovaný rozměr a inicializační hodnotou) pro alokování dynamického pole uvnitř struktur z předchozích bodů (=> funkce bude také template).
    Pokud je parametr rozměru nulový, nastavte všechny proměnné struktury na nulovou hodnotu.
    Pokud je paměť ve struktuře již alokovaná (různá od nullptr), generujte výjimku EAlreadyAllocated.
    Pro alokaci použijte operátor new. Pokud při alokaci dojde k výjimce, přepošlete ji pomocí proměnné ENoMemory předdefinovaného typu TError.
    Hodnotu iCapacity a iSize nastavte na alokovaný rozměr. Pole naplňte hodnotou třetího parametru, který implicitně nastavte na nulu.

  8. Pomocí funkce Allocate inicializujte proměnné d1,d2,d3 na rozměr 10 daný předdefinovanou konstantní hodnotou X (později zkuste vytvořit proměnnou s jiným rozměrem). Zkuste na proměnné i1, že inicializace funguje i pro typ int. Dále pomocí proměnné i1 vyzkoušejte, že při pokusu o opětovnou alokaci je vyvolána vyjimka - vytiskněte chybovou zprávu.

  9. Napište funkci Deallocate pro odalokování alokované paměti ve struktuře TVector. Po odalokování připravte strukturu na možné opětovné použití (tj. vynulujte proměnné).

  10. Napište funkci Print, která vytiskne vektor. V případě, že vektor není alokován, vytiskne se "nealokovano". V případě, že je vektor alokován, se na první řádek vytisknou rozměr iSize a iCapacity oddělené středníkem. Na druhý řádek se vytisknou hodnoty vektoru v hranatých závorkách, oddělené mezerami. Tisk vyzkoušejte na vhodných proměnných.

  11. Napište funkci SetAt, která nastaví prvek na dané pozici na danou hodnotu. První parametr bude struktura, druhý prametr bude index měněného prvku, třetí bude nová hodnota prvku. Při snaze použít prvek mimo využité pole <0;iSize) generujte výjimku EWrongSize.

  12. Napište funkci At, která vrátí hodnotu prvku na dané pozici. První parametr bude struktura, druhý index požadovaného prvku. Při snaze použít prvek mimo využité pole <0;iSize) generujte výjimku EWrongSize.

  13. Napište funkci Add, která sečte hodnoty ve dvou stejně dlouhých vektorech. První parametr je výsledek, další dva parametry jsou sčítanci.
    Ošetřete všechny varianty uvedené v dodaném souboru.


Pro zpřehlednění rozdělte hlavičkový soubor na dva - v prvním budou pouze deklarace funkcí (pouze hlavičky s komentářem parametrů a činnosti - oddělení pro lepší orientaci ); ve druhém souboru budou realizace funkcí. Oba soubory budou hlavičkové, druhý bude includován na konci prvního.




poslední úpravy 2018-10-15