简体   繁体   中英

C++ A polymorphic class, virtual function and casting for performance

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);
  • Would it be ok to skip safety checks, and use a static cast? I have tried it, and it compiles.
  • Would it be ok to skip checks altogether, and do a reinterpret_cast? I have also tried it and it compiles.
  • What is the penalty for doing a dynamic_cast? I know theres a small overhead, but is it anything serious?
  • Is there a way to upcast from State *ptr to S-type *ptr without using a polymorphic class (avoiding the virtual function and simply override it)?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM