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).
Pro předávání parametrů používejte přednostně reference a následně hodnoty.
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).
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.
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).
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.
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.
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.
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.
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é).
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.
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.
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.
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