我有以下课程:
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() 这取决于行为。我宁愿不使用虚函数 bur 覆盖函数 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 类型,以便搜索该状态的策略。现在,因为状态派生类是多态的,我认为这是正确的做法:
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 的惩罚是什么?我知道开销很小,但这有什么严重的吗?
- 有没有办法在不使用多态类(避免虚函数并简单地覆盖它)的情况下从 State *ptr 向上转换为 S-type *ptr?