Sign in to follow this  
whyamibrad

better solution than dynamic_casting?

Recommended Posts

I have a base state machine class that all my state machines inherit from (for example, I make an enemy state machine class that inherits from StateMachine which overloads an update function that holds all the specific state logic for enemies). Now, inside the enemy state machine update function, I need to access member functions that belong to the enemy that owns the state machine. Now, all state machines own an owner pointer, but is stored as a AIGameObject pointer, a base class that all AI objects inherit from. Now, in my enemy state machine update function, I KNOW my owner is an enemy type, so I've been dynamic_cast'ing my AIGameObject pointer to a Enemy pointer. Is there a cleaner way of accessing the Enemy member functions without upcasting like this?

Share this post


Link to post
Share on other sites
Hi,

could you not use templates for your StateMaschines ?



class StateMaschine
{
public:
virtual ~StateMaschine() {}
virtual void update()=0;
virtual void recieveMsg( class Message* msg)=0;
};

template <class T>
class TStateMaschine : public StateMaschine
{
public:
TStateMaschine( T* owner ) : _owner(owner) {}

void setOwner( T* owner ) { _owner = owner; }

protected:
T* _owner;
};

class EnemyStateMaschine : public TStateMaschine<Enemy>
{
public:
EnemyStateMaschine( Enemy* e ) : TStateMaschine(e) {}

void update()
{
_owner->getEnemyBadness(); // :D
}
void recieveMsg(class Message* msg)
{
//...
}
};



Share this post


Link to post
Share on other sites
Hi,

Using dynamic_cast<> can be perfectly valid in a OO design - and it seems that your design needs it (I smell some circular dependencies, but it should not affect your problem). The use of dynamic_cast<> would be tagged as 'not clean' if you were using it in your StateMachine class. But from how I understand it, you have this class hierarchy:

class StateMachine
{
AiGameObject *object;
}
class EnnemyStateMachine : public StateMachine
{
};

If you init EnneyStateMachine with a EnnemyObject, then I don't see any problem with this particular use of dynamic_cast<>.

However there is a solution to avoid the dynamic_cast<>: instead of storing your AIGameObject in the StateMachine class, you only define a virtual method that is used to get the AIGameObject instance. Something along the line of:

class StateMachine
{
virtual AIGameObject *getAIGameObject() = 0;
}
// class EnnemyObject : public AIGameObject { ... }
class EnnemyStateMachine : public StateMachine
{
EnnemyObject *ennemy;
virtual AIGameObject *getAIGameObject() { return ennemy; }
};

Wherever you need the game object in StateMachine, you call the virtual method. There is no real speed penalty because you won't call it 870978 times per frame. You avoid any dynamic_cast<> call - all you do is a simple cast from EnnemyObject to AIGameObject.

HTH,

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this