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

发布于 2024-11-25 10:43:06 字数 1912 浏览 2 评论 0原文

我有以下类:

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 的迭代器,每个操作都有一个 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 而不使用 多态类(避免虚函数并且简单地 覆盖它)?

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)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

能否归途做我良人 2024-12-02 10:43:06

static_castdynamic_cast 之间的区别在于,无效的 static_cast 是未定义的行为,而无效的 dynamic_cast 会导致空指针或 bad_cast 异常(如果您强制转换引用)。 dynamic_cast 的缺点是运行时的类型检查,以及由于 RTTI 而增加的代码大小。

因此,如果您确定强制转换始终正常,则可以安全地使用static_cast。与 static_cast 相比,使用 reinterpret_cast 不会带来任何性能改进,因此您不应在此处使用它。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文