more effective c++ item 31

Discussion in 'C++' started by cfchou@gmail.com, Sep 26, 2005.

  1. Guest

    hi,

    i have one question about the item 31 of Meyers' More Effective c++.
    in page 234, section "Using Virtual Functions Only", it says that
    "for example, you decide to add a new class Satellite (inheriting
    from GameObject) to your game, you'd have to add a new collide
    function to each of the existing classes in the program".

    how come? i assume:

    class Satellite : public GameObject
    {
    void collide(GameObj&){ ... }
    void collide(SpaceShip&){ ... }
    void collide(SpaceStation&){ ... }
    void collide(Asteroid&){ ... }
    };

    then the client code:

    void foo(Satellite& o)
    {
    SpaceShip s;
    s.collide(o); // o.collide(*this)
    }

    SpaceShip has no idea of Satellite, but s still can invoke
    SpaceShip::collide(GameObject& o), and which, in turn, call
    o.collide(*this).
    that's our newly added Satellite::collide(SpaceShip&) implementation.
    and i don't think the existing SpaceShip needs to be added a virtual
    member SpaceShip::collide(Satellite&).

    or i have misunderstanding on this part?

    thank you.
     
    , Sep 26, 2005
    #1
    1. Advertising

  2. wrote:
    >
    > hi,
    >
    > how come? i assume:
    >
    > class Satellite : public GameObject
    > {
    > void collide(GameObj&){ ... }
    > void collide(SpaceShip&){ ... }
    > void collide(SpaceStation&){ ... }
    > void collide(Asteroid&){ ... }
    > };
    >
    > then the client code:
    >
    > void foo(Satellite& o)
    > {
    > SpaceShip s;
    > s.collide(o); // o.collide(*this)
    > }
    >
    > SpaceShip has no idea of Satellite, but s still can invoke
    > SpaceShip::collide(GameObject& o), and which, in turn, call
    > o.collide(*this).
    > that's our newly added Satellite::collide(SpaceShip&) implementation.
    > and i don't think the existing SpaceShip needs to be added a virtual
    > member SpaceShip::collide(Satellite&).
    >
    > or i have misunderstanding on this part?


    You assume, that you know the type of object.

    Look at the follwing:

    std::vector< GameObject* > AllObjects; // Pointers to all objects in the secenery
    // be it SpaceShips, Sattellites, Planets, etc.

    void foo( GameObject* OtherObject )
    {
    for( size_t i = 0; i < AllObjects.size(); ++i )
    if( AllObjects != OtherObject )
    AllObjects->collide( OtherObject );
    }

    A perfectly reasonable function, that checks if some object (no matter what) collides
    with some object object in your scenery.

    At the moment, you know the exact object type, you don't need a virtual function at all.
    Virtual functions enter the picture only in the case that you don't have that information.

    --
    Karl Heinz Buchegger
     
    Karl Heinz Buchegger, Sep 26, 2005
    #2
    1. Advertising

  3. Guest

    hi,
    thank you for the reply.

    but i'm afraid that my example didn't express my
    question very well, sorry for that.

    i write'n compile the following code(omited the
    SpaceStation, Asteroid for clarity):

    #include <iostream>
    using namespace std;
    class SpaceShip;
    class GameObj
    {
    public:
    virtual void collide(GameObj&) = 0;
    virtual void collide(SpaceShip&) = 0;
    };
    class SpaceShip : public GameObj
    {
    public:
    virtual void collide(GameObj&);
    virtual void collide(SpaceShip&);
    };
    void SpaceShip::collide(GameObj& other)
    {
    cout << "SpaceShip hits GameObj => ";
    other.collide(*this);
    }
    void SpaceShip::collide(SpaceShip& other)
    {
    cout << "SpaceShip hits SpaceShip" << endl;
    }

    //====here is the newlly added class====
    class Satellite : public GameObj
    {
    public:
    virtual void collide(GameObj&);
    virtual void collide(SpaceShip&);
    };
    void Satellite::collide(GameObj& other)
    {
    cout << "Satellite hits GameObj => ";
    other.collide(*this);
    }
    void Satellite::collide(SpaceShip& other)
    {
    cout << "Satellite hits SpaceShip" << endl;
    }

    void foo(GameObj& hitter, GameObj& hittee)
    {
    hitter.collide(hittee);
    }

    int main(int argc, char* argv[])
    {
    SpaceShip ss;
    Satellite sl;
    foo(ss, sl);
    foo(sl, ss);
    return 0;
    }

    the result:
    SpaceShip hits GameObj => Satellite hits SpaceShip
    Satellite hits GameObj => SpaceShip hits GameObj => Satellite hits
    SpaceShip

    my point is, althrough SpaceShip didn't know how to hit Satellite, but
    eventually it can let Satellite do the job.
    so, it seems that SpaceShip didn't need to be added a
    "collide(Satellite&)"
    , as long as any newlly added class knows how to hit the existing
    classes.

    i think i must ignore something on this topic, but i can't tell.
    thanks for any help!
     
    , Sep 27, 2005
    #3
  4. wrote:
    >
    > the result:
    > SpaceShip hits GameObj => Satellite hits SpaceShip
    > Satellite hits GameObj => SpaceShip hits GameObj => Satellite hits
    > SpaceShip
    >
    > my point is, althrough SpaceShip didn't know how to hit Satellite, but
    > eventually it can let Satellite do the job.
    > so, it seems that SpaceShip didn't need to be added a
    > "collide(Satellite&)"
    > , as long as any newlly added class knows how to hit the existing
    > classes.
    >
    > i think i must ignore something on this topic, but i can't tell.


    I see now.
    You are assuming that a spaceship hitting a satellite is identical
    to a satellite hitting a spaceship. Well. In this particular example
    that assumption may be ok. But it is not in the general case:

    A op B may not be identical to B op A

    --
    Karl Heinz Buchegger
     
    Karl Heinz Buchegger, Sep 27, 2005
    #4
  5. Guest

    thank you for your patience,
    now i can keep reading on following items.
     
    , Sep 27, 2005
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Don Kim
    Replies:
    9
    Views:
    554
    Gregg
    May 23, 2004
  2. Matthias
    Replies:
    25
    Views:
    995
    Thorsten Ottosen
    Feb 1, 2005
  3. John
    Replies:
    4
    Views:
    647
    Ioannis Vranos
    Apr 27, 2005
  4. Replies:
    1
    Views:
    424
    benben
    Aug 7, 2005
  5. Piotr
    Replies:
    2
    Views:
    329
    Victor Bazarov
    Jan 16, 2006
Loading...

Share This Page