【问题标题】:Why is dynamic_cast considered bad practice in C++?为什么 dynamic_cast 在 C++ 中被认为是不好的做法?
【发布时间】:2014-04-26 03:47:00
【问题描述】:

我知道已经有很多关于这些问题的问题,但我仍然不明白。举个例子:

class Projectile
{
   public:
    virtual void OnCollision(Projectile& other);

   private:
    Vector position;
    Vector velocity;
};
class Bullet : Projectile
{
    // We may want to execute different code based on the type of projectile
    // "other" is.
    void OnCollision(Projectile& other) override;
};
class Rocket : Projectile
{
    // If other is a bullet, we might want the rocket to survive the collision,
    // otherwise if it's a rocket, we may want both to explode.
    void OnCollision(Projectile& other) override;
};

我不明白如果没有 dynamic_cast 怎么能完成这个例子。我们不能只依赖多态接口,因为在这种情况下,它只会为我们提供有关一个对象的信息。有没有办法在没有 dynamic_cast 的情况下做到这一点?

另外,为什么动态转换在 C# 中不被视为不好的做法?它们一直在事件处理程序和非通用容器中使用。在 C# 中可以完成的很多事情都依赖于强制转换。

【问题讨论】:

  • 为什么会有c++标签?
  • @user2485710 因为 dynamic_cast 是 c++,我的例子也是。
  • 好吧,从表面上看,我想说这是一个仅限 C# 的问题,所以你的问题是关于两种语言的。
  • @user2485710 为什么要删除空格...?
  • 我认为可以肯定地说这是重复的 stackoverflow.com/search?q=dynamic+cast+bad ,这里已经有很好的答案了,我想我唯一可以作为旁注添加的是这种of cast 需要 RTTI,在某些情况下这可能被视为令人失望。

标签: c# c++ dynamic-cast


【解决方案1】:

在这个具体的例子中,我会添加一个受保护的方法:

protected:
   virtual int getKickassNess() = 0;

// Bullet:
   int getKickassNess() override { return 10; }
// Rocket:
   int getKickassNess() override { return 9001; }  // over 9000!

void Bullet::OnCollision(Projectile& other)
{
   if (other.getKickassNess() > this->getKickassNess())
      // wimp out and die
}

IMO Bullet 和 Rocket 不应该知道彼此存在。加入这些已知的关系通常会使事情变得困难,在这种特定情况下,我可以想象它会导致混乱的循环包含问题。

【讨论】:

  • 那么,我应该让对象的行为基于它们的属性而不是它们的类型?这很有意义。谢谢。
猜你喜欢
  • 2010-10-22
  • 2011-11-20
  • 2010-11-04
  • 2022-07-05
  • 1970-01-01
相关资源
最近更新 更多