Návrh třídy

může probíhat například takto



  1. Promyslete si, co by měla třída fakticky dělat a co po ní ve finále budete chtít.

    Například projekt: navrhněte třídu pro manipulaci s lineárním seznamem (seznam obsahuje položky hodnota a index). Umožněte vkládání a odstraňování jednotlivých prvků, nebo celých seznamů, třídění podle velikosti (hodnoty nebo indexu), přiřazování seznamů, srovnání položek … Ve druhé fázi umožněte, aby prvky v seznamu mohly být libovolné – například obsahovat hodnoty různých typů. Pro inspiraci. Můžete použít například jako balíček karet a implementovat míchání, rozdávání, jednoduchou hru (válku, oko, prší ...). Postup pro 2D pole je zde.

    Nebo projekt pro realizace grafického elementu, který umožní vykreslení objektů na obrazovce, vytváření těchto objektů, rušení objektů, přiřazování objektů... Začněte jedním grafický elementem: bodem nebo úsečkou, v konečné fázi zkuste kombinovat (společně smíchat) různé typy grafických objektů – pro jejich držení můžete použít například 1D pole nebo seznam. Můžete použít jako příklad nějaký pohyb bodů po obrazovce (variace na screen saver …) například podle stisknuté klávesy, náhodných čísel ...

    Nebo si vytvořte váš vlastní projekt.

  2. Promyslete si kategorie – vznik, zánik, nastavení a zjištění hodnot, manipulace (činnost), operátory, konverze, vstup a výstup, dynamické proměnné, dědění

    U dědění je důležité rozhodnout zda prvek je rozšířením původního, nebo ho obsahuje. Například u grafického elementu je lépe volit, že úsečka obsahuje bod, než že z něj dědí. Jako základ dědění je vhodné uvádět společnou funkčnost a navrhnout tak zvané rozhraní. Metody rozhraní volíme jako virtuální, což nám následně umožní pracovat se zděděnými objekty přes jejich společnou část rozhraní (definovanou přes bázovou třídu). I když zde pracujeme s bázovou třídou, díky mechanizmu virtuálních metod máme k dispozici metody třídy zděděné, které samozřejmě ví o jaký prvek se jedná a dokáží zavolat mu příslušnou metodu.Prvky různých typů zděděných od báze se například mohou vložit do pole ukazatelů na bázový typ a potom se prochází jednotně přes metody rozhraní bez znalosti konkrétního typu (ten si zjišťuje program za chodu z tabulky virtuálních metod – metoda je volána přes adresu, kterou si objekt nese v sobě). Můžeme tak například stejným postupem vykreslit kružnici, čtverec … i když je jasné, že kreslící metoda i datová reprezentace je odlišná.

    Například pro grafický element by mohlo rozhraní obsahovat tyto metody: Vykresli – pro vykreslení všech prvků, Rotuj – pro zrotování pozic všech objektů vůči zadanému středu otáčení, Posuň – pro posunutí všech prvků, VratVzdalenost – pro zjištění minimální vzdálenosti objektu od zadané pozice …

    Například pro lineární seznam by se vytvořil společný prvek který by byl prvkem seznamu a měl základní metody. Pokud by z tohoto základního prvku dědila i třída pro práci se seznamem, choval by se seznam i jako prvek.

  3. Promyslete si datovou reprezentaci a její návaznost na bod 2)

  4. V případě dědění provádějte následující body od bázové třídy.

  5. Vytvořte hlavičkové a zdrojové moduly tříd. Vytvořte modul pro testování tříd (funkce main (či jiná), ve které vyzkoušíme funkčnost napsaných metod). Hlavičkový soubor standardně ošetřete a načtěte ho do zdrojových souborů. Zvažte použití vlastního jmenného prostoru a nadefinujte třídu
    class CTrida { } .

  6. Vytvořte datové členy třídy (měly by se vyskytovat v private sekci). Promyslete jak budete oznamovat (chybový) stav objektu.

  7. Při psaní metod postupujte postupně po krocích tak, že napíšete prázdné tělíčko, vyzkoušíte zda je v pořádku voláno a zda má správně návratovou hodnotu.
    Pro předávání parametrů používejte přednostně referenci. Pro předávání používejte konstantní parametry pro parametry funkce, které se v ní nemění.
    Metody neměnící instanci třídy označte jako konstantní.
    Následně doplňte zdrojový kód metody. Na základě složitosti metody rozhodněte zda bude inline, nebo zda bude ve zdrojové části. U opravdu jednoduchých inline metod napište tělo metody přímo do definice třídy. U inline metod, které jsou delší než jeden řádek dopište inline u deklarace a vlastní tělo metody napište za popis třídy do hlavičkového souboru. Metody s funkčním voláním napište do zdrojového souboru. Pokud je metoda mimo třídu, musí název metody obsahovat upřesnění, ke které třídě patří. To se zajistí pomocí operátoru příslušnosti (Třída::Metoda( ) ).
    Pomocí trasování sledujte proces volání a kudy program „chodí“.

  8. Vytvořte statické datové členy a metody
    U konstruktorů a destruktorů je možné jako kontrolní mechanizmus implementovat počítání vzniklých (konstruktor inkrementuje) a zaniklých (destruktor dekrementuje) objektů pomocí statických objektů. Dále je možné počítat celkový počet vzniklých objektů. Pokud je po skončení programu počet aktivních proměnných různý od nuly je někde chyba. Pro tisk statických proměnných se používají statické metody, které lze použít i pro případ, kdy není vytvořená žádná instance.
    Vytvořte statické proměnné pro uložení počtu aktivních a vytvořených prvků (v definici třídy je deklarace proměnných, definice je v cpp souboru). Ke zjištění počtu aktivních a celkových prvků vytvořte statické metody. Vlastní funkce pro tisk bude volat tyto metody.
    { int i= CTrida::PocetVytvorene(); // pomocná proměnná - žádný objekt třídy
    TiskVytvorenych(); TiskAktivnich();
    {
    CTrida p1; //implicitni
    TiskVytvorenych(); TiskAktivnich();
    }//tady se volaji destruktory
    i = 5; // zde už by neměl „žít“ žádný objekt třídy
    TiskVytvorenych(); TiskAktivnich();
    }

  9. Vytvořte konstruktory a destruktory
    Jelikož konstruktory (pro nastavení/inicializaci) a destruktory (pro „uklizení“) používají části kódu, které jsou využitelné i v jiných metodách (například přiřazení, změny rozměrů, nastavení do základního tvaru...) je výhodné pro tyto vytvořit samostatné metody z konstruktorů volané. V případě „nebezpečných“ metod (ke kterým by neměl mít uživatel přístup, jako je alokace a odalokace paměti ...) je nutné tyto uvést v private sekci.

    Pro testování například tato část kódu
    { int i= CTridat::PocetAktivni(); // pomocná proměnná - žádný objekt třídy
    TiskVytvorenych(); TiskAktivnich();
    {
    CTrida p1; //implicitni
    CTrida p2 = 3, p6 = 3.1; // konverzní z int, double
    CTrida p3 = p2, p4(p3); // kopy
    CTrida p5 (
    "3, 2,0"); // konverzní z char*
    CTrida p7 (3,2,0), p8(3,2); // (použit jeden společný) konstruktor se třemi (a také dvěma) parametry (pro třetí parametr použita implicitní hodnota)
    CTrida p8[4]; // pole prvků třídy
    CTrida *pp = (CTrida*) new CTrida(2,4,1); // dynamické vytvoření pomocí konstruktory se třemi parametry
    --- tady něco chybí ---
    TiskVytvorenych(); TiskAktivnich();
    }//tady se volaji destruktory
    i = 5; // zde už by neměl „žít“ žádný objekt třídy
    TiskVytvorenych(); TiskAktivnich();
    }

  10. Vytvořte metody pro zadávání a čtení dat (Gettery a Settery)

    Pro testování například tato část kódu
    p1.SetX(4); // při nastavení se může například změnit rozměr, k čemuž použijeme privátní metody (alokace, odalokace, které jsme použili pro konstruktory)
    p2.SetY(5);
    p3.SetXY(3,4); // rozměry x,y; u seznamu počet a hodnota ...
    ix = p4.GetX();
    iy = p5.GetY();

    Ověřte, že nefunguje přístup ke členským datům třídy: aa = p1.proměnná; musí dát chybu

  11. Vytvořte metody pro výpočty (manipulaci)

    Například pro vázaný seznam: vložení prvku, seřazení podle daného kriteria, načtení prvku, zařazení prvku, vložení seznamu, tisk, rušení prvku, zjištění počtu prvků, volného indexu, maximálního indexu … ,
    Například pro grafiku – zadání souřadnic, zjištění minimální a maximální hodnoty souřadnice, rotace, translace, určení zda je na obrazovce (ve vybraném regionu), vyhledání nejbližšího elementu k určenému bodu, vykreslení …)

    Pro testování například tato část kodu
    p1.Vypocti(); p2.Srovnej(p1); // metody s jedním parametrem (+ volající objekt (this))
    p5.Pridej(p1,p2,65); p2.Uprav(); // metoda se třemi parametry a bez parametrů (+ volající objekt (this))
    p3.Invertuj(); // naimplementujte tak, že metoda invertuje p3, p3 je po operaci změněná
    p4.Srovnej(Invertuj(p3)) ;// funkce invertuje p3 a je implementována tak, že se p3 nezmění, následně se výsledek inverze p3 srovná s p4 (podle vhodného kriteria)

  12. Vytvořte operátory a konverze

    Například pro lineární seznam: připojení seznamu pomocí + (a+b), vytvoření seznamu s „otočením“ znamének hodnot v seznamu pomocí - (-a s tím, že respektuje stejná pravidla jako základní typy (int, float) a tedy a je i po operaci stejné jako před ní), ukázat rozdíl oproti + (+a), přiřazení = (a=b), test na shodu seznamu == (a==b), zjištění zda obsahuje hodnotu (a== 34) …
    Nebo u grafiky: přiřazení = (a=b), pro „zrcadlení“ prvku - (-a), ukažte rozdíl s + (+a), výpočet „průměru“ dvou bodů a = (b+c)/2; násobení konstantou pro zvětšení/zmenšení a = b *2; a *= 2; přičtení konstanty pro posuv, zjištění zda dva body jsou totožné a==b

    Pro testování například tato část kodu
    p1 = p2 = -p3 + p4 * p5; // přiřazení (zřetězené/vícenásobné), unární mínus, plus a krát (objekt * objekt)
    if (p1 <= p2) p1 -= +p5 * 8; // logický operátor <= pro srovnání, unární plus, operátory „-=“ a krát (objekt*int)
    else p1 -= 3*p4; // operátor „-=“, nečlenský operátor (realizován funkcí) int*objekt
    float f = p1 != p3; // logický operátor je různé „!=“ (vrací typ bool)
    int i = (int)p5; // konverzní operátor (objekt se převede na int)

  13. Vytvořte funkce/metody pro vstup a výstup

    Tyto metody by měly být doplňkové. To znamená, že alespoň jeden z typů vstupu by měl být schopen načíst data pořízená výstupem.

    Pro testování například tato část kodu
    {cout << " ted si vypisu hodnoty me tridy " << p1 << " a pro srovnani " << p2 << "\n zadejte hodnoty noveho prvku";
    cin >> p5;
    ifstream is(
    "nacti.dat",ios::in); is >> p4; }

  14. Konec programování = začátek testování - vytipujeme si různé kombinace vstupních parametrů a vyzkoušíme, zda se jednotlivé metody chovají podle předpokladů (nejlépe provádět přímo po implementaci každé nové metody).























Poslední úpravy 2010-11-17