C++ 多态类、虚函数和性能转换

标签 c++ polymorphism downcast upcasting

我有以下类(class):

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();
};

还有其他类都继承自State。它们的区别仅在于它们如何评估取决于行为的 isTerm() 。 我宁愿不使用虚函数,而是重写函数 isTerm,如果不是因为有一些其他模板化类被设计为与各种状态派生类一起工作。 其中之一是政策:

template <class S>
class Policy
{ 
  protected:    
    float QValue;
    S *state;
    S *nextState;
  public:
    ...
    template <class P>
    void updateOptimal(boost::ptr_vector<P> &policies);
}

updateOptimal 必须获得一个 State 派生类(取决于行为),从 State *ptr 向上转换为当前使用的任何 S 类型,以便搜索该状态的策略。现在,因为 State 派生类是多态的,我认为这是正确的做法:

S *s = dynamic_cast<S *>(iter->getNextState());

其中 iter 是 Actions 的迭代器,每个 action 都有一个指针 State *nextstate; action->nextstate 设置在其他点:

action->setNextState(dynamic_cast<State *>(state)); 

我可以模板化整个类 Action,以避免使用 State *nextstate; 并使用 S *nextstate; 但这需要在整个过程中进行大量更改项目。

cplusplus.com 上阅读类型转换教程据我了解,最好使用 dynamic_cast,因为它会在向上或向下转换之前进行类型检查。 但是,在转换后的以下代码中,除了用于搜索之外,我没有对向上转换状态做任何事情:

P *temp_pol = var::findPolicy(policies,s);

findPolicy 在哪里:

template <class P, class S>
P* findPolicy(boost::ptr_vector<P> &policies,S *state);
  • 可以跳过安全检查并使用静态转换吗?我 已经尝试过了,它可以编译。
  • 是否可以完全跳过检查并进行 reinterpret_cast ? 我也试过了,它可以编译。
  • 执行 dynamic_cast 的惩罚是什么?我知道有一个小 开销,但这有什么严重的吗?
  • 有没有办法在不使用 一个多态类(避免虚函数,简单地 覆盖它)?

最佳答案

static_castdynamic_cast 的区别在于,无效的static_cast 是未定义的行为,而无效的dynamic_cast导致空指针或 bad_cast 异常(如果您转换引用)。 dynamic_cast 的代价是在运行时进行类型检查,并且由于 RTTI 增加了代码大小。

因此,如果您确定转换总是正确的,则可以安全地使用 static_cast。使用 reinterpret_cast 不会比 static_cast 有任何性能提升,因此您不应该在这里使用它。

关于C++ 多态类、虚函数和性能转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6766889/

相关文章:

c++ - shared_ptr 不能为空?

swift - 在 Swift Core Data 中向下转换 NSManagedObject

c++ - mingw32-make : *** No targets. 停止

c++ - 系统找不到指定的文件 Visual Studio 2015

c++ - 选择在 cmake 中构建库或可执行文件

c++ - 如何多态地使用数组或指针 vector ?

c++ - 如何实现具有另一个派生类的协变返回类型的函数?

haskell - 在 Haskell 中描述一般图形的类型类

java - 为什么在这种情况下向下转型会抛出 ClassCastException?

java - 为什么向下转换抛出异常?