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).



  1. 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.

  2. 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).

  3. 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.

  4. 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.

  5. 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).

  6. 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.

  7. 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.

  8. 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.

  9. 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.

  10. 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é).

  11. 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.

  12. 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.

  13. 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.

  14. 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.

  15. 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.

  16. 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