.[ ČeskéHry.cz ].
virtualní metody :: interface
Jdi na stránku 1, 2  Další
 
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> C / C++
Zobrazit předchozí téma :: Zobrazit následující téma  
Autor Zpráva
VODA



Založen: 29. 07. 2007
Příspěvky: 1721
Bydliště: Plzeň

PříspěvekZaslal: 19. prosinec 2008, 18:43:12    Předmět: virtualní metody :: interface Odpovědět s citátem

Zdravím,

narazil jsem teď na jeden problém, kdy odlazuji jisté třídy...no a vknížce jsem si přečetl, že v Javě a C# se to dělá pomocí interfaců...
C++ pro interfacy nemá podporu, ale narozdíl od jazyků Java a C# podporuje vícenásobonou dědičnost...
Takže podle knížky se to dá udělat pomocí virtuálních metod...

V knížce je třída popsána takhle:
kód:
class muj_interface
{
      public:
           virtual int metoda() const = 0;
};


Jenže když napíší const, tak mi kompilátor vyhodí toto...i přestože mám v odvozené třídě definici této metody...zde... přesně tak jak je psáno v moudré knize...

No a když deklaraci napíšu takto, tak se mi to vyhodí tohle...

Co to teda po mně chce (anglicky umím, takže pochopím, že mám virtuální metodu, ale nemám virtuální destruktor), jenže co se po mě chce ze strany programátorské...v DEV-CPP to po mě nic nechtělo a v Eclipsu najednou tohle...přitom používám stejný kompilátor jako v Devku...

Najednu stranu je to jen varování a kód chodí v pohodě, ale na stranu druhou bych chtěl, aby mi to nehlásilo varování (nedej bože chyby Very Happy ) žádné...

Tak díky za radu...
_________________
Opravdovost se pojí s trýzní...
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
VODA



Založen: 29. 07. 2007
Příspěvky: 1721
Bydliště: Plzeň

PříspěvekZaslal: 19. prosinec 2008, 18:49:31    Předmět: Odpovědět s citátem

Nechapu jak je to možné, ale teď jsem tam zkusil napsat virtuální destruktor (do definice odvozené třídy) a už to to varování nehlásí...

Nj...ale co znamená, že jsem udělal virtuální destruktor?
_________________
Opravdovost se pojí s trýzní...
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Marek



Založen: 28. 07. 2007
Příspěvky: 1782
Bydliště: Velká Morava

PříspěvekZaslal: 19. prosinec 2008, 19:06:50    Předmět: Odpovědět s citátem

Když máš třídy Derived dědí Base, použiješ volání Base *b = new Derived; a potom delete b; u virtuálních destruktorů se zavolají všechny, jak bys čekal. U normálních se zavolá pouze ten u Base, žádný jiný.
_________________
AMD Open Source Graphics Driver Developer
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Marek



Založen: 28. 07. 2007
Příspěvky: 1782
Bydliště: Velká Morava

PříspěvekZaslal: 19. prosinec 2008, 19:09:44    Předmět: Odpovědět s citátem

Ještě něco - je to daleko zajímavější. Nejenže se nezavolá destruktor u Derived, ale nezavolají se ani destruktory u členských proměnných třídy Derived. Když se nezavolají destruktory u těch členských proměnných, nezavolají se ani u těch proměnných, které ty členské proměnné vlastní... a tak dále. Špatně se takové chyby pak hledají...
_________________
AMD Open Source Graphics Driver Developer
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
VODA



Založen: 29. 07. 2007
Příspěvky: 1721
Bydliště: Plzeň

PříspěvekZaslal: 19. prosinec 2008, 19:21:13    Předmět: Odpovědět s citátem

Aha, takže jestli to dobře chápu...pokud mám nějakou dědičnost, tak je dobré mít virtuální konstruktory...???
Nebo teda...
Pokud bych věděl, že budu používat pouze případ, že DERIVED *d = new DERIVED; tak je to asi jedno ne?
Na druhou stranu...kdyby to bylo jedno, tak by mi asi překladač nehlásil varování...hm zajímavé...

Předpokládám, že je to otázka polymorfismu...takže bych si měl opětovně projít kapitolu o polymorfismu... Wink
_________________
Opravdovost se pojí s trýzní...
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Marek



Založen: 28. 07. 2007
Příspěvky: 1782
Bydliště: Velká Morava

PříspěvekZaslal: 19. prosinec 2008, 19:30:21    Předmět: Odpovědět s citátem

Jo. Každý objekt, co je součástí dědičné hierarchie, by měl mít virtuální destruktor. Naopak ostatní objekty by ho neměly mít virtuální, protože to není úplně efektivní a hlavně ho compiler neumí udělat inline.
_________________
AMD Open Source Graphics Driver Developer
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
VODA



Založen: 29. 07. 2007
Příspěvky: 1721
Bydliště: Plzeň

PříspěvekZaslal: 19. prosinec 2008, 19:40:24    Předmět: Odpovědět s citátem

Ok, tak těď už tomu rozumím, díky za objasnění...

Přeci jenom jednu věc bych ještě chtěl vědět...

Co udělá s virtuální metodou to const za závorkama (viz první příspěvek) -> virtual void metoda() const = 0;

Mě prostě překladač vyhodí že je metoda abstraktní a nejde vytvořit instance odvozené třídy...znovu opakuji instance odvozené třídy...což je divné...já myslel, že když je třída abstraktní, tak nejde zinstancovat, ale lze od ní odvodit třída, která musí mít poviné definice metod z abstraktní třídy...

??
_________________
Opravdovost se pojí s trýzní...
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
OndraSej



Založen: 28. 07. 2007
Příspěvky: 767
Bydliště: Brandýs nad Labem

PříspěvekZaslal: 19. prosinec 2008, 19:56:32    Předmět: Odpovědět s citátem

To const za nazvem metody rika, ze ta metoda "nemeni" obsah tridy a tedy muze byt volana i na konstantnich instancich te tridy. Pozor na to, ze void debug_me() a debug_me() const jsou dve odlisne (!!) metody. Takze prekladac nadava proto, ze jsi v odvozene pretizil debug_me(), zatimco abstraktni debug_me() const zustava nedefinovana.

Jinak to, ze je metoda abstraktni neznamena, ze ji musis napsat do primo odvozene tridy. To ne, kdyz ji nenapises, tak proste i ta odvozena bude abstraktni a takhle to jde opakovat, jak dlouho chces.
_________________
http://trionteam.net
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
VODA



Založen: 29. 07. 2007
Příspěvky: 1721
Bydliště: Plzeň

PříspěvekZaslal: 21. prosinec 2008, 13:20:04    Předmět: Odpovědět s citátem

Objevil se další problém s operátorama...nechce se mi zakládat nový topic...možná to bude i souviset s tímto topicem...

Zkrátka...mám objekt CNULL, měli by ho dědit všechny třídy, abych mohl zjistit, jestli už byl objekt zinicializován nebo ne...

Má dva operátory pro == a != a paramter je enum, který má dvě hodnoty defined a undefined...

No vše funguje do té doby, než chci přidat do nějaké třídy, která CNULL dědí, operátor ==, vyhodími to "no match for operator== in trida == undefined (nebo defined)"...
Teda pokud operátor nadefinovaný v CNULL použiju...

Já myslel, že se operátory taky dědí a přetěžují se...ale tohle mi nějak nejde do hlavy... možná to mám blbě navržené...
Doufám, že správné řešení nebude přidání další abstraktní metody a definování jí v každé třídě...což je stejnak divný, když pro všechny třídy by tato metoda měla být stejná... vrací se true nebo false v závislosti na tom jestli je atribut c_state nadtřídy CNULL roven nebo neroven parametru operátoru (defined nebo undefined)...

Já tomu nechápu... Wink
_________________
Opravdovost se pojí s trýzní...
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Yossarian



Založen: 28. 07. 2007
Příspěvky: 274
Bydliště: Šalingrad

PříspěvekZaslal: 21. prosinec 2008, 13:23:33    Předmět: Odpovědět s citátem

zkus ten operator == udelat const, popripadne.
friend bool operator == (const CNull& c, const CNull2& c);
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
VODA



Založen: 29. 07. 2007
Příspěvky: 1721
Bydliště: Plzeň

PříspěvekZaslal: 21. prosinec 2008, 13:55:26    Předmět: Odpovědět s citátem

Pro upřesnění...

Mám třídu CNULL nadeklarovanou takto...je tam vidět i enum...

Definice CNULL pak takto (jen s chybou v operátoru != kdy za return nemá být == ale !=, ale to už je opravené)

No a když chci v odvozené třídě operátor== s jiným parametrem...zde...a použiji operátor z CNULL, tak mi to vyhodí tu chybu...zde...(VEC c; na začátku)

Nevím co s tím...potřebuji operátory oba dva....chci porovnávat jestli se atributy tříd rovnají a zároveň chci zjistit jestli je třída definována nebo ne...
_________________
Opravdovost se pojí s trýzní...
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Marek



Založen: 28. 07. 2007
Příspěvky: 1782
Bydliště: Velká Morava

PříspěvekZaslal: 21. prosinec 2008, 17:13:28    Předmět: Odpovědět s citátem

Když má metoda stejnej název v potomkovi jako v předkovi, ta v předkovi se potlačí. Jsou 2 způsoby, jak to řešit. První prostě řekne, ať se použije metoda z konkrétní třídy přes operator ::, druhá pak používá přetypování na referenci předka:

kód:
if (c.CNULL::operator==(undefined)) ...

kód:
if ((CNULL&)c == undefined) ...


Ovšem řešit defined/undefined u typů je jednak zbytečnost a za druhé chytřejší lidi použijí normální metodu namísto operátoru. Tohle je pěknej příklad, kde jsou operátory prostě použity špatně.
_________________
AMD Open Source Graphics Driver Developer
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
rezna



Založen: 27. 07. 2007
Příspěvky: 2156

PříspěvekZaslal: 21. prosinec 2008, 18:29:29    Předmět: Odpovědět s citátem

Eosie napsal:
Ovšem řešit defined/undefined u typů je jednak zbytečnost a za druhé chytřejší lidi použijí normální metodu namísto operátoru. Tohle je pěknej příklad, kde jsou operátory prostě použity špatně.


tak tak - operator ma vyjadrovat to co znamena ve skutecnosti - nikoliv je priohybat totalnim prasarnam.

tady se mnohem lepe hodi metoda bool IsDefined() a jeste lepe IsInitialized() pokud nas opravdu zajima samotna inicializovanost objektu
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
VODA



Založen: 29. 07. 2007
Příspěvky: 1721
Bydliště: Plzeň

PříspěvekZaslal: 22. prosinec 2008, 09:15:00    Předmět: Odpovědět s citátem

Hm, asi jo...
Já jen chtěl udělat podobnou věc z maxscriptu...tam když se objeví nějaká chyba nebo vracím neexistující objekt tak se vrátí undefined...

No nic no...se nic nestane když to "zase" předělám... Wink
_________________
Opravdovost se pojí s trýzní...
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
rezna



Založen: 27. 07. 2007
Příspěvky: 2156

PříspěvekZaslal: 22. prosinec 2008, 09:22:37    Předmět: Odpovědět s citátem

VODA napsal:
Hm, asi jo...
Já jen chtěl udělat podobnou věc z maxscriptu...tam když se objeví nějaká chyba nebo vracím neexistující objekt tak se vrátí undefined...

No nic no...se nic nestane když to "zase" předělám... Wink


v C++ se vraci NULL - od toho to tam je Wink
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Zobrazit příspěvky z předchozích:   
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> C / C++ Časy uváděny v GMT + 1 hodina
Jdi na stránku 1, 2  Další
Strana 1 z 2

 
Přejdi na:  
Nemůžete odesílat nové téma do tohoto fóra
Nemůžete odpovídat na témata v tomto fóru
Nemůžete upravovat své příspěvky v tomto fóru
Nemůžete mazat své příspěvky v tomto fóru
Nemůžete hlasovat v tomto fóru


Powered by phpBB © 2001, 2005 phpBB Group


Vzhled udelal powermac
Styl "vykraden" z phpBB stylu MonkiDream - upraveno by rezna