Programovanie v jazyku C++

Objektovo orientované programovanie


Trieda a objekty

Základnou vlastnosťou objektovo-orientovaných jazykov je možnosť tvorby nových dátových typov nazývaných triedy. Trieda z filozofického pohladu abstrahuje spoločné vlastnosti jej inštancií, objektov. Za triedu by sme mohli prehlásiť aj napríklad dátový typ int a všetky čísla typu int za inštancie tejto triedy. C++ je ale na rozdiel od napr. Javy alebo Smalltalku hybridným jazykom a na to, aby sme mohli nejaký dátový typ prehlásiť za triedu musia byť splnené niektoré podmienky.

Základnými vlastnosťami triedy sú

Objekt ako inštancia triedy musí mať nasledujúce vlastnosti Je zrejmé, že jednoduchý dátový typ, ako napr. int tieto požiadavky nespĺňa. Na tomto mieste treba spomenúť, že niektoré programovacie jazyky hlavne z databázovej oblasti o sebe prehlasujú, že sú objektovo orientované, napriek tomu nemajú vyššie spomenuté vlastnosti. Pre takéto jazyky sa zaužívalo označené object based.

Vytvorme triedu Ratio reprezentujúcu množinu racionálnych čísel. Trieda Ratio musí obsahovať dva atribúty - čitatela a menovatela a metódy na manipuláciu s atribútmi. Od triedy Ratio budeme požadovať, aby bola kompatibilná s ostatnými štandardnými dátovými typmi C++. Pre znázornenie tried a vzťahov medzi triedami budeme používať sémantiku OMT. Trieda Ratio v sémantike OMT potom bude mať tvar podla obrázka.

Od triedy Ratio budeme vyžadovať, aby mala také isté vlastnosti, ako ktorýkoľvek iný dátový typ. Musíme vedieť vytvoriť jednotlivé objekty, polia objektov, vytvárať objekty staticky aj dynamicky.

Požadované vlastnosti triedy Ratio

Ratio ra;                    // racionalne cislo 0/1
Ratio rb(3);                 // racionalne cislo 3/1
Ratio rc(3,4);               // racionalne cislo 3/4
Ratio rd[10];                // pole 10 racionalnych cisel 0/1 
Ratio *re;                   // smernik na racionalne cislo
Deklarácia triedy Ratio sa v C++ podobá deklarácii štruktúry. Okrem atribútov triedy obsahuje trieda ešte metódy triedy a metódy inštancií. Metódy triedy patria triede objektov, typickými metódami triedy sú metódy na vytváranie a mazanie objektov - konštruktor a deštruktor. Metódy objektov sú určené na manipuláciu s objektami, v objektovo orientovanej terminológii je tento pojem zhodný s pojmom správy posielanej objektu.

Deklarácia jednoduchého prototypu triedy Ratio

class Ratio {
  protected:
    int numerator;            // citatel
    int denominator;          // menovatel
  public:
    Ratio();                  // konstruktory
    Ratio(int);
    Ratio(int, int);
    int numerator();          // pristupove metody k atributom
    int denominator();
};
Deklarácie tried sú zvyčajne umiestnené v hlavičkových súboroch (header file). Je vhodné pomenovať hlavičkový súbor podla triedy, ktorá je v ňom deklarovaná. Prípona hlavičkového súboru závisí od operačného systému počítača, zvyčajne býva .hpp alebo .H. Implementácia metód býva v zdrojových súboroch (source file) s označením .cpp alebo .C.

Deklarácia triedy začína klúčovým slovom class nasledovaným menom triedy. Riadok

protected:
vymedzuje viditelnosť časti deklarácie triedy v dedičnej štruktúre. Atribúty a metódy ktoré nasledujú za týmto klúčovým slovom budú viditelné pre eventuálnych potomkov triedy Ratio, nie sú ale prístupné pre objekty iných tried. Je to akási forma rodinného vlastníctva. Okrem tohoto typu môže byť deklarované výhradné súkromné vlastníctvo typu private - atribúty a metódy sú prístupné len tým objektom triedy, v ktorej sú deklarované alebo komunistické vlastníctvo typu public - ktokolvek môže manipulovať s atribútmi a používať metódy.

Časť deklarácie

int numerator;
int denominator;
deklaruje atribúty triedy. Je potrebné vedieť, že okrem užívatelom deklarovaných atribútov triedy pridáva kompilátor k atribútom ešte jeden atribút, pomocou ktorého je definovaná identita objektov triedy. Je ním smerník takého dátového typu, ako je trieda sama a jeho meno je this. Pri vytvorení inštancie triedy - nového objektu obsahuje tento smerník adresu začiatku pamäťového priestoru, kde je objekt umiestnený.
Za deklaráciou "verejnej" časti triedy nasledujú deklarácie metód. Prvými troma sú konštruktory. Konštruktor sa od bežnej metódy alebo funkcie odlišuje tým, že nevracia žiadnu hodnotu. Naše tri konštruktory nám zabezpečujú vytváranie rôznych druhov objektov podla našich požiadaviek
Ratio();                  
Ratio(int);
Ratio(int, int);
C++ nám umožňuje tvorbu funkcií alebo metód s rovnakým menom a rôznymi typmi argumentov a návratových hodnôt. Toto je nazývané preťaženie (overloading) mena funkcie. Za týmto zázrakon sa v skutočnosti skrýva jednoduchý mechanizmus zámeny mien funkcií kompilátorom. Kompilátor si vytvára pred procesom kompilácie nové mená funkcií, ktoré pozostávajú z pôvodného mena a prefixov resp. postfixov, ktoré závisia od argumentov funkcie, jej eventuálnej príslušnosti k nejakej triede a návratovej hodnoty.
Pretože naše tri konštruktory v podstate realizujú tú istú operáciu - inicializáciu racionálneho čísla rozličným množstvom argumentov, je vhodné konštruktory zlúčiť do jedného. V C++ môžeme funkciu deklarovať s prednastavenými (default) argumentami:
Ratio(int=0, int=1);
Pokial použijeme prednastavené argumenty funkcie, nemôžeme už pre danú kombináciu argumentov použiť preťaženie mena funkcie, pretože nám kompilátor vyhlási nejednoznačnosť mena funkcie.

Trieda môže mať neobmedzené množstvo konštruktorov (za podmienok uvedených výššie), ale najviac jeden deštruktor.