more effective c++ item 31

C

cfchou

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.
 
K

Karl Heinz Buchegger

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.
 
C

cfchou

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!
 
K

Karl Heinz Buchegger

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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,226
Members
46,815
Latest member
treekmostly22

Latest Threads

Top