I'm looking to pass a base object pointer through a virtual function, and in overriden methods of the virtual function, I want them to recognize the derived pointer, not the base pointer. Here is an example
class Base{
};
class Derived : Base{
};
class ExternalClass{
public:
virtualvoid Function(Base *){
//code stops here, but this function does nothing, since I want the overriding function to be called
}
}
class ExternalClassDerived : ExternalClass{
public:
virtualvoid Function(Derived *p){
//do something with p
//however the code never reaches here
}
}
Here is my actual code, as the above example is a little sparse.
class WorldObject{
//...
};
class Entity : public WorldObject{
public:
Entity();
virtualvoid Update(){
input->Update(this);
}
Input *input;
};
class Input{
public:
//...
virtualvoid Update(WorldObject *){
//this is where the function call ends, so nothing gets done because this
//method is purposefully empty
}
};
class MeleeEntityAI : public Input{
public:
MeleeEntityAI(){}
virtual ~MeleeEntityAI(){}
virtualvoid Update(Entity *o);
};
void MeleeEntityAI::Update(Entity *o){
//desired behavior, never called
}
Entity::Entity(){
input = new MeleeEntityAI();
}
But if I ever call Function and pass it a Base pointer, then Function(Derived*) is never called; the call stops at Function(Base*). How can I get Function(Derived*) to be called when I am passing a Base* to it?
You are not overriding the method Function in ExternalClassDerived. In order to override a function, the function must have the the same number and types of arguments in the overriding function.
If you're accessing your ExternalClassDerived instance via a pointer or reference to ExternalClass all that is visible is the ExternalClass::Function(Base*) method, and since it isn't overridden, that is what is called.
I see. So how do I accomplish the behavior defined in Function(Derived*) when I am passing a derived pointer but I only have access to Function(Base*)?
I''ve posted my actual code above, since I may have over-abstracted.
Avoid it if possible, since it's a fairly costly operation in most implementations. If the function definitely needs a Derived then you have no choice but to either dynamic_cast or to redesign.
You may want to google for double dispatch to see another approach to solving the problem.
I've implemented double dispatch for my collision resolution, but it seems so overkill here just to handle AI, since I'd have to forward declare every derived class.
I had no trouble getting it to work with double dispatch, but as my list of derived classes increases, this code may become a little unwieldly
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
class Entity;
class MeleeEnemy;
class Jumper;
class WorldObject;
class Input{
public:
Input(){
ClearInputs();
}
virtual ~Input(){}
//override these in derived classes from Input
virtualvoid Update(Entity *g){}
virtualvoid Update(MeleeEnemy *g){}
virtualvoid Update(Jumper *g, /*and other params*/){}
//...
};