OOP z pohľadu C/Asm programátora

06.02.2008 11:47 | vid

Pre veľa programátorov nižších jazykov je objektovo orientované programovanie (OOP) záhadnou oblasťou plnou zdanlivo nezmyselných abstrakcii. V tomto článku postupne vystaviam a vysvetlím niektoré aspekty OOP z pohľadu programátora v C alebo Assembleri.

(Tento článok je trochu experiment: Niesom si istý, či je toto vhodný spôsob vysvetľovania OOP. Takže som zvedavý na reakcie. Čitateľnejšiu verziu článku nájdete TU)

Upozorňujeme, že jazyková syntax v príkladoch nie je vždy 100% správna - uprednostnil som čitateľnosť.

Na čo je objektové programovanie vlastne dobré? Všeobecne by sa dalo povedať, že umožňuje pomocou jednotného interfacu pristupovať k rôznym typom "objektov" (dátových štruktúr), ktoré majú podobné vlastnosti. Robí to kvázi štandardizovaným, a čistým spôsobom. Najlepšie to ale pochopíte, keď uvidíte v praxi o čo sa jedná.

Prvý objekt

Najprv si musíme vedieť predstaviť, čo to taký objekt je. Pekný príklad sú objekty v počítačovej hre. Predstavme si, že vyvíjame vlastnú počítačovú hru. V hre budú existovať nejakí nepriatelia, zbrane, letiace náboje, bonusové predmety, atď. Všetko toto budeme reprezentovať ako objekt, ktorý zatiaľ vnímajme ako dátovú štruktúru v pamäti.

Každý objekt je nejakého typu. Typ objektu môže byť napríklad napríklad lekárnička, ktorá doplní energiu. Samozrejme, v hre môže byť naraz viac lekárničiek. Všetky lekárničky sa správajú rovnako, až na niekoľko atribútov ktoré môžu byť u jednotlivých lekárničiek odlišné (koordináty udávajúce, kde na mape sa lekárnička nachádza, množstvo energie ktorú lekárnička doplní). Typ objektu sa v OOP terminológii nazýva "trieda" ("class"). Jednotlivé objekty tohoto typu sa nazývajú "inštancie triedy" ("class instance"). Atribúty, ktoré sú rôzne pre každú inštanciu, sa nazývajú "dátové členy" objektu ("data members")

Dohodnime sa, že naše objekty budú začínať číslom (veľkosti dword), ktoré udáva typ objektu. Zaťiaľ budeme mať iba jeden typ, lekárničku (TYPE_MEDIKIT). Ďalej budú nasledovať dátové členy, podľa typu objektu. Pre lekárničku to budú: koordináty X,Y, a množstvo energie ktorú doplní. Deklarácia objektu typu lekárnička na súradniciach [10,15], ktorá doplní 50 bodov energie potom bude vyzerať následne:
Asm:

dd TYPE_MEDIKIT ;typ objektu = lekárnicka
dd 10 ;x koordinát = 10
dd 15 ;y koordinát = 15
dd 50 ;energia = 50

C:
struct MEDIKIT {
int type;
int x, y;
int hp;
};
MEDIKIT mk = {TYPE_MEDIKIT, 10, 15, 50};

Teraz si zadefinujme ďalší objekt: mínu. Mína bude svojím spôsobom opak lekárničky: keď sa jej hráč dotkne, uberie mu zo života. Takisto bude mať koordináty, a množstvo energie ktoré uberie. Navyše však bude mať ďalší atribút (resp. dátový člen), a to čas, ktorý ubehne odkedy sa hráč dotkne míny, dokým mína vybuchne. Náš objekt môže vyzerať takto:
Asm:

dd TYPE_MINE ;typ objektu = mina
dd 10 ;x koordinát = 10
dd 15 ;y koordinát = 15
dd 5 ;cas vybuchnutia = 5 sekúnd
dd 50 ;energia = 50

C:
struct MINE {
int type;
int x, y;
int timeout;
int hp;
};

Pri pristupovaní k objektu, si najprv zistíme jeho typ, ktorý je u všetkých typov objektov v prvom dworde. Potom podľa typu poznáme množstvo a význam nasledujúcich dátových členov.

Metódy

Zamyslime sa nad tým, ako vyzerá program pracujúci s takými objektami, ako sme ich definovali doteraz. Konkrétne pre náš príklad, ako vyzerá časť programu, ktorá zabezpečuje ošetrenie a spracovanie kontaktu hráča s objektom. Neuvažujeme časť, ktorá zisťuje, či nejaký kontakt nastal, iba časť, ktorá spracúva udalosť, keď už nastal kontakt hráča s niektorým objektom.

Najprv musíme zistiť, aký je to typ objektu (akej triedy je objekt inštanciou), a podľa toho sa zariadiť ďalej. Ak je typ objektu "lekárnička", doplníme hráčovi energiu a objekt odstránime z hry (aby sa nedala tá istá lekárnička používať stále dokola). Ak je typ objektu "mína", začneme odpočítavanie do vybuchnutia míny.
Asm:

;esi = adresa objektu
cmp dword [esi], TYPE_MEDIKIT
je handle_medikit
cmp dword [esi], TYPE_MINE
je handle_mine

C:
struct OBJECT {
int type;
} *obj;
...
switch(obj->type) {
case TYPE_MEDIKIT:
MEDIKIT *mk = (MEDIKIT*)obj;
...
case TYPE_MINE:
MINE *mn = (MINE*)obj;
...

Tento prístup má však praktický problém. Časti programu pracujúce s konkrétnym typom objektu sú roztrúsené po celom programe pri udalosti, ktorú spracúvajú (napr. dotknutie hráča a objektu). Takto, ak chceme zmeniť nejaký aspekt správania sa objektu, musíme vyhľadať a opraviť všetky miesta v programe. Ľahko sa môže stať, že niektoré vynecháme a potom musíme zdĺhavo hľadať, kde nastala chyba.

Lepší prístup je mať pokope celý kód pracujúci s určitým typom objektov (tj. s konkrétnou triedou). Vyriešime to tak, že pre každý typ objektu (pre každú triedu) dáme kód, čo s ňou pracuje do samostatných funkcii, a tieto zoskupíme podľa triedy, ktorú obsluhujú. V našej ukážke budeme mať teda funkciu, ktorá bude obsahovať kód na spracovanie kontaktu hráča s lekárničkou a ďalšiu na spracovanie kontaktu s mínou. Funkcie budú mať ako argument adresu objektu (inštancie), pre ktorú su volané:
Asm:

cmp dword [esi], TYPE_MEDIKIT
jne not_medikit
push esi
call medikit_touched
jmp done
not_medikit:
cmp dword [esi], TYPE_MINE
jne not_mine
push esi
call mine_touched
jmp done
not_mine:

C:
switch(obj->type) {
case TYPE_MEDIKIT:
medikit_touched((MEDIKIT*)obj);
break;
case TYPE_MINE:
mine_touched((MINE*)obj);
break;

Takéto funkcie, ktoré pracujú s konkrétnou triedou, nazývame "metódy" triedy.

Ukážka, ako takáto metóda môže vyzerať. Každá metóda má štandardne ako prvý argument ukazovateľ na objekt (inštanciu triedu), s ktorým pracuje. Tento pointer sa štandardne nazýva "this" pointer:
Asm:

MEDIKIT.X = 8
MEDIKIT.Y = 12
MEDIKIT.HP = 16
;pri volani, ESI=ukazovatel na objekt
medikit_touched:
mov esi, [esp+4] ;nacitaj argument zo zasobniku
mov eax, [esi + MEDIKIT.HP]
add [player.hp], eax ;doplnime zivot hracovi
mov [esi + MEDIKIT.HP], 0 ;lekarnicka vycerpana
mov [esi + MEDIKIT.X], -1 ;odsunieme lekarnicku doprdele
mov [esi + MEDIKIT.Y], -1
retn 4

C:
void medikit_touched((MEDIKIT*)this) {
player.hp += this->hp; // doplnime zivot hracovi
this->hp = 0; // lekarnicka vycerpana
this->x = -1; // odsunieme lekarnicku doprdele z mapy
this->y = -1;
}

Virtualne metódy

Ešte stále to však nieje ono. Stále musíme, pri pridaní novej triedy, pridávať na veľa miest kód, ktorý zisťuje typ objektu a podľa toho volá príslušnú metódu. Je to možné riešiť aj elegantnejšie.

Priamo do objektu vložíme pointer na metódu, a potom pri volaní metódy už netreba zisťovať typ objektu, ale len priamo zavolať metódu, na ktorú sa odkazuje:
Asm:

; objekt typu lekarnicka
dd TYPE_MEDIKIT ;typ objektu = lekarnicka
dd medikit_touched ;ukazovatel na metodu "touched"
dd 10 ;x koordinat = 10
dd 15 ;y koordinat = 15
dd 50 ;energia = 50
; objekt typu mina
dd TYPE_MINE ;typ objektu = mine
dd mine_touched ;ukazovatel na metodu "touched"
dd 10 ;x koordinat = 10
dd 15 ;y koordinat = 15
dd 5 ;time to explode = 5 seconds
dd 50 ;damage = 50
; volanie metody "touched" objektu, na ktory ukazuje ESI
push esi ;adresa objektu
call dword [esi+4] ;volanie metody podla pointeru

C:
struct MEDIKIT {
int type;
void (*touched)(OBJECT* this); // ukazovatel na metodu "touched"
int x, y;
int hp;
};
struct MINE {
int type;
void (*touched)(OBJECT* this); // ukazovatel na metodu "touched"
int x, y;
int timeout;
int hp;
};
struct OBJECT { // spolocna struktura pre vsetky objekty
int type;
void (*touched)(OBJECT* this); // ukazovatel na metodu "touched"
} *obj;
// volanie metody "touched" pre objekt "obj"
obj->touched(obj);

Virtuálna tabuľka

Zadefinujme si ďalšiu metódu. Môže to byť napriklad metóda "shot", ktorá bude zavolaná, keď hráč strelí do objektu. Podľa doterajšieho systému to bude vyzerať asi takto:
Asm:

; objekt typu lekarnicka
dd TYPE_MEDIKIT
dd medikit_touched
dd medikit_shot ;pridali sme ukazovatel na druhu metodu
dd 10
dd 15
dd 50
; objekt typu mina
dd TYPE_MINE
dd mine_touched
dd medikit_shot ;pridali sme ukazovatel na druhu metodu
dd 10
dd 15
dd 5
dd 50
; volanie metody "touched" objektu, na ktory ukazuje ESI
push esi ;adresa objektu
call dword [esi+4] ;volanie metody podla pointeru
; volanie metody "shot" objektu, na ktory ukazuje ESI
push esi ;adresa objektu
call dword [esi+8] ;volanie metody podla pointeru

C:
struct MEDIKIT {
int type;
void (*touched)(OBJECT* this);
void (*shot)(OBJECT* this); // pridany ukazovatel na metodu "shot"
int x, y;
int hp;
};
MEDIKIT mk = {TYPE_MEDIKIT, &medikit_touched, &medikit_shot, 10, 15, 50};
struct MINE {
int type;
void (*touched)(OBJECT* this);
void (*shot)(OBJECT* this); // pridany ukazovatel na metodu "shot"
int x, y;
int timeout;
int hp;
};
MINE mn = {TYPE_MINE, &mine_touched, &mine_shot, 10, 15, 50};
struct OBJECT { // spolocna cast
int type;
void (*touched)(OBJECT* this);
void (*shot)(OBJECT* this); // ukazovatel na metodu "shot"
} *obj;
// volanie metody "touched" pre objekt "obj"
obj->touched(obj);
// volanie metody "shot" pre objekt "obj"
obj->shot(obj);

Pre úplnosť si môžeme ukázať aj príklady týchto metód. Metóda "medikit_shot" spôsobí, že energia lekárničky sa zníži na polovicu, a "mine_shot" spôsobí okamžity výbuch míny (nastaví "timeout" na nulu).
Asm:

medikit_shot:
mov esi, [esp+4]
mov eax, [esi + MEDIKIT.HP]
shr eax, 1
mov [esi + MEDIKIT.HP], eax
retn 4
mine_shot:
mov esi, [esp+4]
mov dword [esi + MINE.TIMEOUT], 0
retn 4

C:
void medikit_shot(MEDIKIT *this)
{
this->hp = this->hp / 2;
}
void mine_shot(MINE *this)
{
this->timeout = 0;
}

Tu už začíname vidieť problém s týmto prístupom. Každý objekt má v sebe ukazovatele na metódy triedy. Avšak pre všetky inštancie tej istej triedy sú tieto ukazovatele rovnaké. To znamená, že každým objektom zbytočne plytváme pamäť tým viac, čím viac je metód.

Riešením je zadefinovať pevne tabuľku ukazovateľov raz pre každú triedu a do objektov dať len ukazovateľ na každú triedu. Táto tabuľka sa nazýva "virtuálna tabuľka" (virtual table). Týmto spôsobom je navyše ukazovateľ unikátny pre objekty každej triedy a teda sa zároveň dá využiť na určenie typu objektu (to je ale málokedy treba, keďže všetku prácu s objektom vykonáme priamo v metódach). To znamená, že člen "type" už nie je potrebný.
Asm:

; virtualna tabulka triedy MEDIKIT
medikit_vtab:
dd medikit_touched
dd medikit_shot
; instancia triedy MEDIKIT
mk:
dd medikit_vtab ;adresa virtualnej tabulky
dd 10 ;x
dd 15 ;y
dd 50 ;hp
; virtualna tabulka triedy MINE
mine_vtab:
dd mine_touched
dd mine_shot
;instancia triedy MINE
mn:
dd mine_vtab ;adresa virtualnej tabulky
dd 20 ;x
dd 20 ;y
dd 30 ;timeout
dd 50 ;hp
;volanie metody "touched" objektu na ktory ukazuje ESI
push esi ;argument pre metodu
mov eax, dword [esi] ;EAX = adresa virtualnej tabuly
call dword [eax] ;EAX+0 = adresa metody "touched" vo virtualnej tabulke
;volanie metody "shot" objektu na ktory ukazuje ESI
push esi ;argument pre metodu
mov eax, dword [esi] ;EAX = adresa virtualnej tabuly
call dword [eax+4] ;EAX+4 = adresa metody "shot" vo virtualnej tabulke

C:
// deklaracia spolocnej virtualnej tabulky
struct VTAB {
void (*touched)(OBJECT* this);
void (*shot)(OBJECT* this);
};
// lekarnicka
struct MEDIKIT {
VTAB *vtab;
int x,y;
int hp;
};
VTAB medikit_vtab = {&medikit_touched, &medikit_shot}; // virtualna tabulka triedy MEDIKIT
MEDIKIT mk1 = {&medikit_vtab, 10, 15, 50};
MEDIKIT mk2 = {&medikit_vtab, 20, 20, 10};
// mina
struct MINE {
VTAB *vtab;
int x,y;
int timeout;
int hp;
};
VTAB mine_vtab = {&mine_touched, &mine_shot}; // virtualna tabulka triedy MINE
MINE mn1 = {&mine_vtab, 10, 15, 30, 30};
// spolocna cast vsetkych objektov
struct OBJECT {
VTAB *vtab; // uz iba vtab
};
OBJECT *obj;
// volanie metody "touched" objektu na ktory ukazuje "obj"
obj->vtab->touched(obj);
// volanie metody "shot" objektu na ktory ukazuje "obj"
obj->vtab->shot(obj);

Poznámka: V praxi väčšina metód triedy nemusí byť virtuálnych, a kompilátor (ak je to možné) dokáže zavolať tu správnu metódu sám. Virtuálne metódy majú skutočný význam pri dedičnosti, ktorá v tejto časti ešte nebola zadefinovaná (aj keď v príkladoch sme ju mali, bez toho aby sme o tom vedeli).

Pokračovanie nabudúce?

To je zatiaľ všetko. Pokiaľ bude dobrá odozva na článok, možno napíšem aj pokračovanie, kde podobným štýlom rozoberiem aj niektoré ďalšie aspekty moderného objektového programovania.

    • Re: OOP z pohľadu C/Asm programátora 06.02.2008 | 17:34
      Avatar fiwo   Používateľ

      prisiel jeden kometar mailom tak ho tu preposielam:

      urcite nech ten clanok pokracuje lebo je to dobre napisane a konecne viem
      co je to objektove programovanie no mam este otazku... Ked naprogramujeme
      tie instrukcie pre dany objekt tak ten objekt [napr. lekarnicka]musi byt
      vytvorena ako nejaky graficky objekt no a teraz konecne otazka>Ten objekt
      staci normalne vytvorit v nejakom grafickom editore? napr. gimp? alebo ako
      to funguje... Dakujem ze odpoved.

      Sent from http://blackhole.sk/feedback by Martin.

      • Re: OOP z pohľadu C/Asm programátora 06.02.2008 | 23:31
        Avatar vid   Používateľ

        typico... dnes som moc najebany.... zatra bude odpoved

        Inac ma potesil clovek, ktory asi 1.5 minuty po uverejneni mi dal skore 2/5, som rad ze si si to tak dokladne precital...

        • Re: OOP z pohľadu C/Asm programátora 07.02.2008 | 01:41
          Avatar blackhole_tommyhot   Používateľ

          Ja som ten clanok len tak na rychlo prebehol, ale je dost dobre napisany. Objekty som sice nikdy nevedel poriadne pochopit ale po zbeznom precitani sa mi zacina vyjasnievat =)

          5* len tak dalej
          ----------
          tommyhot@hackingmachine:~$ microsoft &> /dev/null

      • Re: OOP z pohľadu C/Asm programátora 07.02.2008 | 07:52
        Avatar vid   Používateľ

        v OOP sa "objekt" mysli ako programatorsky pojem - datova struktura v pameti + funkcie (metody) co s nou pracuju.

        To ako objekt zobrazis v podstate s tymto nesuvisi. Vela objektov je aj takych ktore nezobrazujes (napriklad nejake "triggery", ktorych ked sa hrac dotkne (tj. prijde na urcite miesto na mape), tak sa nieco udeje).

        Ale ak chces robit hru, tak ano, treba si spravit nejaku grafiku, a jedna z "metod objektu" byva zvycajne vykreslenie objektu v momentalnom stave v akom je.

    • Re: OOP z pohľadu C/Asm programátora 07.02.2008 | 04:13
      Avatar blackhole   Návštevník

      urcite dobry uvod do oop problematiky ;)
      predtym som o tom viacmenej len pocula

    • Re: OOP z pohľadu C/Asm programátora 07.02.2008 | 11:48
      Avatar blackhole   Návštevník

      No ja a programing niesme kamarati takze tak... ale clanok to jasne vysvetluje aspon co sa tyka objekt. programovania... :P privitam viac... hodnota minimalne 5bodov

    • Re: OOP z pohľadu C/Asm programátora 07.02.2008 | 22:57
      Avatar neo177   Používateľ

      velmy dobry clanok... doteraz som si myslel ze objektove programovanie programuje objekty niekde v nejakom engine, nie ze je to len datovy objekt niekde v pamati...

    • Re: OOP z pohľadu C/Asm programátora 08.02.2008 | 03:57
      Avatar blackhole   Návštevník

      Osobne nemam objektove programovanie velmi rad, ta koncepcia mi pripada relativne zbytocna, ale musim uznat, ze ked uz napr. v C++ daco robim, vzdy vidim aj pekne veci na tom. Clanok je zaujimavy v tom, ze berie OOP v podstate do dosledku, teda po uroven stroja, co je pred beznym OOP programatorom absolutne skryte, z coho vyplyvaju dalsie veci/problemy, povedzme "moderneho" programovania. O tom pojednava celkom zaujimavy clanok na itnews.
      V kazdom pripade zaujimavy clanok a dufam, ze bude pokracovanie, priniesol (aspon mne) trochu svetla do "zakulisia" OOP, ktore je celkom zaujimave a podla mna by mnohokrat napr. aj vyucbu OOP obohatilo. Je to pravy opak pristupu "ked soferujem auto, nepotrebujem vediet ako funguje motor, hlavne, ze si to dokazem odsoferovat". Ja radsej viem "ako to auto funguje", preto sa mi clanok pacil. Vecne pripomienky po dokladnejsom precitani:-).

      Co z toho, ze zajtra bude lepsie, ked vzdy, ked sa zobudim, je dnes!!!

      • Re: OOP z pohľadu C/Asm programátora 08.02.2008 | 04:40
        Avatar vid   Používateľ

        Ja s tebou suhlasim, tiez sa prijemnejsie citim v nejakom "miesanom jazyku", kde mozem kombinovat klasika proceduralne programovanie a globalne veci, a pouzit objekty tam kde maju vyznam.

        Ono objektove programovanie je skor nasledok praktickych problemov proceduralneho programovania, nikdy som to nevnimal ako nejaku samostatnu paradigmu.

        Napriklad v proceduralnom programovani sa casto ze "alokujes zdroje" (otvoris handle, alokujes pamat, atd...), ale zabudnes ich uvolnit. Hlavne v pripade chyby (predcasny navrat z funkcie) je to dost o zivot, ustrazit si co vsetko treba zavriet. A pritom toto je vec ktoru za nas dokaze ustrazit pocitat, tak naco sa s tym srat rucne? A vznikol strukturovany exception handling a automaticky volany destruktor.

        Dalej pri vecsich programoch ma 90% funkcii nejaky "this" pointer, na data s ktorou funkcia pracuje. Obcas je to mierne otravne, stale ho vsade podsuvat. V objektovom programovani je to metoda, a this pointer je automaticky.

        Podobne napriklad obmedzenie "scope" pri objektovom programovani: pomoze to odchytit niektore chyby uz pri kompilacii. A vo vynimocnych pripadoch ked to potrebujes obijst, tak mas v C++ prikaz "friend".

        Proste na velke veci je objektove programovanie vyborna vec, ulahcuje to kopec veci. Ale ked sa to da do ruk niekomu kto nechape co je za tym, tak velmi casto to dopadne tak, ze silou mocou bude chciet vsetky specialne vlastnosti pouzivat, aj ked netreba.

        • Re: OOP z pohľadu C/Asm programátora 08.02.2008 | 11:10
          Avatar blackhole   Návštevník

          Nj, ale si nespomenul este dost dolezitu vec v OOP - dedenie. (Oprav ma ak sa mylim, v proceduralnych moc nerobim...) To je podla mna vec, ktora v proceduralnom jazyku nema obdobu hlavne dovoluje pouzivat navrhove vzory - a to je IMO velmi velky plus.

          Btw na margo toho clanku na itnews - tam sa hovorilo konkretne o Jave, ktora je zasa dost specificka. Nie celkovo o OOP.
          ==
          ROFLMAO is when you ROFL too much.

          • Re: OOP z pohľadu C/Asm programátora 08.02.2008 | 11:21
            Avatar vid   Používateľ

            dedicnost sa mi uz nechcelo pisat, bude nabuduce:

            Virtuálne metódy majú skutočný význam pri dedičnosti, ktorá v tejto časti ešte nebola zadefinovaná (aj keď v príkladoch sme ju mali, bez toho aby sme o tom vedeli).

            vyzera ze to pokracovanie napisem, zatial je v plane:
            - dedicnost
            - strukturovane spracovavanie vynimiek
            - nejaky vseobecny obkec okolo Garbage Collectoru

            ak ta este nieco napada co by tam malo byt, tak daj vediet

          • Re: OOP z pohľadu C/Asm programátora 08.02.2008 | 21:23
            Avatar blackhole   Návštevník

            Jasne, hovorilo sa o Jave, nie vseobecne o OOP, ale zober si, ze cisto OOP jazyky v podstate naozaj stavaju urcitu nepreniknutelnu stenu medzi to, co pise tvorca a co spracovava stroj, proste ludia, ktori nikdy v zivote nic neprogramovali a predhodia im rovno dake C# alebo Java-u, sa asi tazko budu zaujimat o pozadie a to je podla mna ten problem, nerad by som bol zle pochopeny. Prave v tom sa mi ten clanok paci, ze vysvetluje OOP na nizkej urovni - C/Asm a nebolo by na skodu vediet co a ako sa deje v stroji... Mam trosku alergiu na pristup jedneho cloveka od nas zo skoly(aj ked klobuk dolu pred nim, o tom potom), ktory obhajuje opak, teda ze staci vediet robit vo vyssom jazyku, takze sa mozno nechavam strhnut emociami:-). Samozrejme OOP neodsudzujem, ved ako som povedal v C++ robim, dokonca sa mi veci z OOP vedia aj hovadsky zapacit(polymorfizmus), len ma mrzi to (nutene) odddelenie pozadia problemu od tych krasnych zdrojakov, ktore sa pisu. Aj ked zas Java je podla mna hrozna...
            A k exception handling a garbage collector - pekne veci, len obcas sa rad bavim prave s tym, ze hladam memory leaky atd., co samozrejme je len moja mala radost a pri vacsom projekte je automatika nepochybne velkou pomocou.

    • Re: OOP z pohľadu C/Asm programátora 08.02.2008 | 20:09
      Avatar blackhole   Návštevník

      Zujimavy clanok. Neviem si ani spomenut ci som vobec nieco podobne uz videl. Ale tie kody vyzeraju naozaj odstrasujuco pre mna ... ked oop tak jednoznacne java. S tymto by som naozaj pracovat nechcel. Ked budem najblizsie na javu nastvany urcite si to este pozriem aby ma to preslo :D.

      • Re: OOP z pohľadu C/Asm programátora 09.02.2008 | 14:54
        Avatar vid   Používateľ

        Ono takto sa to v praxi nekodi vecsinou. Jedine priklady v realnom svete su COM a jeho kopia GObject (z GTK kniznice), a to je fakt humus. Zvycajne nema zmysel paprat sa v tom rucne, ked mame C++, javu, a C#.