[ vladaboy93 @ 21.06.2009. 13:03 ] @
Ovako znaci imam 3 klase, ( ustvari ih je mnogo vise, ali da bi bio jednostavniji primer ), jedna klasa je osnovna ,Thing klasa, i iz nje sam izveo mnogo klasa, sad funkcija za proveru sudara je ista za sve objekte, i zato prima parametre opste klase Thing, ali ukoliko je doslo do sudara, mora doci do razlicitih reakcija, i zbog toga mi treba pristup promenjivama iz klasa koje su nasledile klasu Thing..

Code:

#define PLAYER 1
#define ENEMY 2
#define WALL 3

class Thing
{
public:
    virtual void update()=0;
    virtual void draw()=0;
        int TYPE;
};


class Player : public Thing
{
public:
        int vx , vy;
        Player()
        {
             TYPE=PLAYER;
        }
}

class Enemy : public Thing
{
public:
        int vx , vy;
        bool chase;
        Enemy()
        {
             TYPE=ENEMY;
        }
}


i sad imam funckiju

collision( Thing *A, Thing *B )
{
       if(A.TYPE==PLAYER && B.TYPE==WALL)   
       {
                if(collision_test(A,B))
                      A.vx=0;                                     // PROBLEM, nemam pristup vx
       }

       if(A.TYPE==PLAYER && B.TYPE==ENEMY)   
       {
                if(collision_test(A,B))
                      B.chase=true;                                 //PROBLEM, nemam pristup promenjivi chase... 
       }

      ...............................
}

Moze li se ovo nekako resiti?
[ Mihajlo Cvetanović @ 21.06.2009. 17:02 ] @
Može dinamičkim kastovanjem (moraš da uključiš RTTI opciju u kompajleru):

dynamic_cast<Player*>(A)->vx = 0;
...
dynamic_cast<Enemy*>(B)->chase = true;

A može i virtuelnom funkcijom onCollision klase Thing koja je nasleđena u klasama Player i Enemy:

Code:
class Thing
{
public:
    virtual void onCollision();
};

Player::onCollision()
{
    vx = 0;
}

Enemy::onCollision()
{
    chase = true;
}
[ NastyBoy @ 22.06.2009. 01:24 ] @
To je tipicni problem gde overload funkcije treba da se desi na osnovu tipa argumenata (poznatiji kao Multimethod, ili multiple-dispatch). Moze da se resi na vise nacina, od cast-ovanja do, recimo, visitor patterna.

Za uvod u temu pogledaj: http://en.wikipedia.org/wiki/Multiple_dispatch - primer dat u ovom linku je slican tvom.
[ Goran Arandjelovic @ 22.06.2009. 13:44 ] @
Citat:
NastyBoy: To je tipicni problem gde overload funkcije treba da se desi na osnovu tipa argumenata (poznatiji kao Multimethod, ili multiple-dispatch). Moze da se resi na vise nacina, od cast-ovanja do, recimo, visitor patterna.

Za uvod u temu pogledaj: http://en.wikipedia.org/wiki/Multiple_dispatch - primer dat u ovom linku je slican tvom.


Multiple dispatch je priča za sebe. Postoje tu mnogi problemi, a neki od njih su eksponencijalno uvećavanje broja grana za proveru u odnosu na broj argumenata koji treba da se dispatch-uju, zatim problem simetrije, problem overloading-a kod nasleđivanja, itd... To se rešava type listama, meta algoritmima za sortiranje tipova u listi od najizvedenijeg do baznog i meta f-jama za prolaz kroz tu listu... + eventualno swapovanje argumenata zbog simetrije, tako da je verovatno bolje da se ne bavi time ni u kom obliku trenutno već da uradi otprilike kako je Mihajlo rekao čisto da nebi gubio vreme (a i malo su ružni oni primeri na Wikipediji).


--
@vladaboy93
Uradi onako kao što ti je Mihajlo rekao, uz jednu napomenu: Ako si već u nekoj if grani pitao kog je tipa neki objekat (sa onim tvojim int-om A->TYPE i B->TYPE, itd...), onda unutar te grane ti ZNAŠ o kom tipu je reč, tako da tu slobodno mesto dynamic_cast-a koristi static_cast.
[ NastyBoy @ 22.06.2009. 14:59 ] @
Ne bih se slozio. Prvo, sto ce za svaku sledecu stepenicu u detekciji/razresenju kolizije da se namuci da pokrpi to ad-hoc resenje, a drugo sto ne mora da implementira komplikovana resenja bazirana na templejtima da bi dobio prihvatljivo (i skalabilno sa brojem tipova) resenje.
[ vladaboy93 @ 22.06.2009. 17:02 ] @
nisam znao za ovaj dinamicki kast, posluzice, hvala.
[ Goran Arandjelovic @ 22.06.2009. 18:37 ] @
@Bojan

- C/C++ primer sa Wikipedije uopšte nije "čisto" rešenje ako nekim datim handlerom collision_** želiš da pokriješ čitavu podhijerarhiju, a ne samo jedan tip.
- Drugi C++ primer je opet nezgodan, imaš eksponencijalni rast grananja, a i uvođenjem novih tipova u hijerarhiju treba da izvršiš adekvatne izmene (da paziš na redosled grana da neki opštiji slučaj nebi slučajno "progutao" nešto što ne treba...)

Jednostavno rečeno, ili handleri ne smeju da imaju znanje o tome kakva je hijerarhija ili proces kreiranja grana za ispitivanje treba automatizovati.
E da, možda si me pogrešno razumeo, oba ta primera jesu elegantnija nego neko skroz pešačko rešenje, ali su opet nezgodna za održavanje. Neko (dobro) templejt rešenje je mnogo teže implementirati, ali takve stvari već postoje tako da i ne moraju da se implementiraju od nule...