Třída CVector - začátek
Realizujte třídu CVector na základě dodané funkce main a následujících pokynů.
V návaznosti na tvoření kódu pro třídu CVector 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).
Při
tvorbě třídy CVector vycházejte z kódu vytvořeného pro minulé
cvičení (template struct CVector). Původní kód odstraníme z
překladu podmíněným překladem a budeme ho postupně upravovat pro
třídu.
Využijeme i kód již realizovaných funkcí, které budeme
postupně upravovat na metody. Tedy tak, aby vyhovovaly mechanizmům
třídy.
Volání funkcí převedeme na metody
tak, že první parametr funkce bude volat metodu (, který se tedy
přesune před název funkce a nebude již v sekci parametrů).
Vlastní
definice funkce (realizovaná mimo třídu) se na metodu převede tak,
že se před její název uvede název třídy s operátorem příslušnosti.
Dále první parametr (typu CVector)
se odstraní z parametrů – v metodě se objeví pomocí
implicitního ukazatele this.
Vytvořte
nový projekt.
V něm vytvořte soubor main_c
(do něj
překopírujte dodaný kód) s funkcí
main.
Z
minulého projektu si překopírujte soubory s vytvořeným template
vektorem (vector.h,
vector.cpp …).
Funkce s těly nakopírujte z hlavičkového do zdrojového souboru.
V hlavičkovém souboru ponechejte jen hlavičky funkcí.
V
hlavičkovém i zdrojovém souboru umažte definici šablony (template
<typename T>)
před definicemi funkcí.
Obsah hlavičkového i zdrojového souboru
vylučte z překladu pomocí #if
0 … #endif.
Pro
kontrolu paměti přidejte soubory knihovny check: check.cpp
a check.h.
Include souboru check.h
přesuňte z
hlavičkového do zdrojového souboru vector.cpp.
Pomocí hromadného přejmenování přejmenujte TVector
na CVector
(ve všech
souborech).
V souboru vector.h nadefinujte pomocí using datový typ pro data ve vektoru (zvolte double). Nový datový typ pojmenujte stejně jako jste používali název datového typu v typename šablony (tj. T, Type, TType …). Tento nový typ používejte všude tam, kde má proměnná přímou souvislost s datovým typem pole.
Nadefinujte třídu pro typ CVector.
Proměnné pro členská data budou iData, iSize (počet
uložených prvků) a iCapacity (dostupné místo pro uložení
prvků). Proveďte implicitní nastavení členských dat na nulové
hodnoty.
Pro prvky spojené s polem používejte typ definovaný
pomocí using.
Ve funkci main (v bloku try) definujte proměnné d1,d2,d3 třídy CVector. Objekty jsou inicializované díky inicializaci prvků třídy (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 veřejnou metodu Size
pro zjištění aktuální délky vektoru. Metoda bude bez parametrů,
vracet bude počet prvků využitých pro uložení hodnot vektoru. Metodu
napište v definici třídy (tj. inline
metoda).
Ve funkci main zavolejte tuto metodu pro objekt
d1.
Napište metodu Allocate (se
dvěma parametry: první pro požadovaný rozměr a druhý pro
inicializační hodnotou) pro alokování dynamického pole uvnitř třídy
z předchozích bodů.
Metodu vytvořte ve zdrojovém souboru (nebude
inline) úpravou funkce Allocate z minulého cvičení.
Pokud
je paměť ve třídě již alokovaná (různá od nullptr), generujte
výjimku EAlreadyAllocated.
Pokud je parametr rozměru
nulový, nastavte všechny proměnné třídy na nulovou hodnotu.
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í metody 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). Dále pomocí proměnné d1 vyzkoušejte, že při pokusu o opětovnou alokaci je vyvolána vyjimka - vytiskněte chybovou zprávu.
Napište metodu Deallocate (ne inline) pro uvolnění alokované paměti ve třídě CVector. Po odalokování připravte třídu na možné opětovné použití (tj. vynulujte proměnné).
Napište metodu 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 inline metodu At, která bude sloužit pro nastavení i čtení prvku na dané pozici. Jediný parametr bude index prvku se kterým se pracuje. Návratovou hodnotou bude reference na prvek v poli s daným indexem (metoda At bude tedy použitelná ke čtení (na pravé straně operátoru =) i k nastavení (na levé straně operátoru =) prvku). Při snaze použít prvek mimo využité pole <0;iSize) generujte výjimku EWrongSize.
Napište
privátní inline metodu IntegrityCheck – 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).
Pozn. u třídy již nemá tato funkce takový význam
jako u struktury, protože u třídy může s private proměnnými
manipulovat pouze autor a ten by neměl dopustit aby se proměnné
dostaly do stavu, kdy si neodpovídají. Tato funkce má tedy smysl
pouze pro ladění, pro upozornění na chybu, kterou je nutné opravit.
Napište metodu Equal s parametrem typu CVector (reference). Tato metoda provede kontrolu, že oba vektory jsou shodné včetně hodnot (iCapacity se může lišit). Vrací bool.
Napište inline metodu Compatible s parametrem typu CVector (reference). Metoda provede kontrolu, že oba objekty jsou alokované a uložená data jsou stejně dlouhá (stejné iSize). Metoda vrací příslušný TError.
Napište metodu Add, která
sečte hodnoty ve dvou stejně dlouhých vektorech. Dva parametry
metody jsou sčítanci. Výsledek se uloží do objektu, který metodu
vyvolal.
Ošetřete všechny varianty uvedené v dodaném souboru. Pro
kontrolu vhodnosti vstupních parametrů pro výpočty v metodě použijte
metody z předchozích bodů (např. Compatible).
poslední úpravy 2018-10-16