I have the following classes:
class State
{
protected:
Vec3D accel;
Vec3D gyro;
Vec3D gps;
float reward;
public:
boost::ptr_vector<Action> actions;
...
virtual bool isTerm();
}
class guState : public State
{
float gps_stand_thres;
float gps_down_thres;
public:
guState(Agent &A,ACTION_MODE &m);
bool isTerm();
};
There are other classes which all inherit from State. Their differences solely lie on how they evaluate isTerm() which depends on behavior. I would rather not use virtual functions bur override function isTerm, if it wasn't for the fact that there are a few other templated classes which are designed to work with all sorts of State-derived classes. One of them is Policy:
template <class S>
class Policy
{
protected:
float QValue;
S *state;
S *nextState;
public:
...
template <class P>
void updateOptimal(boost::ptr_vector<P> &policies);
}
updateOptimal has to obtain A State-derived class (depending on behavior), up-cast from a State *ptr to whatever the S-type being currently used is, in order to search for policies for that state. Now, because State-derived classes are polymorphic, I assumed it was the right thing to do:
S *s = dynamic_cast<S *>(iter->getNextState());
where the iter is an iterator of Actions and each action has a pointer of State *nextstate;
action->nextstate is set at some other point:
action->setNextState(dynamic_cast<State *>(state));
I could template the entire class Action, in order to avoid using State *nextstate;
and use S *nextstate;
but that would require an enormous amount of changes throughout the project.
Reading the casting tutorial on cplusplus.com it is my understanding that it is best to use dynamic_cast because it does a type check before up or down casting. However in the following code after casting I do not do anything to the up casted state other than use it for searching:
P *temp_pol = var::findPolicy(policies,s);
where findPolicy is:
template <class P, class S>
P* findPolicy(boost::ptr_vector<P> &policies,S *state);
The difference between static_cast
and dynamic_cast
is that an invalid static_cast
is undefined behavior, while an invalid dynamic_cast
results in a null-pointer or a bad_cast
-exception (if you cast references). The penalty for a dynamic_cast
is a type-check during runtime, and increased code-size due to RTTI.
So, if you are sure that the cast is always fine, you can safely use static_cast
. Using reinterpret_cast
would not give you any performance-improvement over static_cast
, so you shouldn't use it here.