Hey, I'm here again for questions about multiple inheritance and virtual methods. Well actually, I don't think MI affects this, I'll try to stick to the point.
In a physics engine I'm working on, I have a class called solid. All objects of this class have hitboxes and can collide with others. I have the following methods:
1 2 3 4 5 6 7 8
void testCollision(something begin, something end);
/* This method takes a container's begin and end iterators to
test if the object collides with any other object of the list
of all the solids currently in the game area. Each time there
is a collision, it calls collide(other) and other.collide(*this) */
virtualbool collide(solid& other);
/* This method always returns false and does nothing */
This class will be inherited by another class which will have overloads for a few specific collisions. For example:
1 2 3 4 5 6
class player : public solid{
public:
bool collide(projectile& other);
bool collide(enemy& other);
bool collide(wall& other);
};
My question is quite simple actually. If I have a loop which calls testCollision() with all elements in the list of all solids (a list of pointers to solids to be exact) and there is a collision between the player and a projectile, will testCollision call player::colide(projectile& other) or will it call solid::collide(solid& other). And in any case, did I understand how to use the virtual keyword? If I'm right, it should call the player::colide method if it's there for the specific type, else it will call the solid::colide which only returns 0, ignoring collision.
I do not think you have overridden collide(solid &other) because the types you specified functions for in player are not direct solids. I also think you should declare player's functions here as:
virtualbool collide(projectile &other) override;
When collide is called and dynamic dispatch is activated; it means it can not automatically downcast correctly to any other type; you'll have to specify a function:
virtualbool collide(solid &other) override;
in player so that you can try downcasting the "other" reference and call the correct implementation. You can also copy the collide functions from player into the solid class in order to get your desired result, but you may implicitly up-cast in testCollision, and thus call the collide(solid &other) virtual function.
To answer your question, I think your function will call solid's collide function and not dispatch anything further because nothing matches the signature down the inheritance chain.
I see that you always put the solid& other as const. I guess that makes more sense since we call other.collide(*this). I don't need to do much in terms of physics, it's a space shooter so collisions are mostly there to deal damage and destroy entities. However, the current object will be modified, so the method itself isn't const.
I guessed it wouldn't be as magical as I put it in my first post, but I didn't know about dynamic casting, which does pretty much what I've been looking for.
But in this case, would it be simpler or quicker to simply hold a variable representing the type of solid? Oh no, because a projectile would have a getDamage() method required by the player, which an enemy wouldn't have... Dynamic cast seems to be the solution here. Well thanks a lot, you're always the one finding the solution to my problems here!
> would it be simpler or quicker to simply hold a variable representing the type of solid?
We do not need it when RTTI is already there.
In any case, maintaining such a variable with correct semantics is not as trivial as it would appear at first sight.
(For instance, the implicitly declared copy constructor would not do at all).