【问题标题】:When must/should dynamic_cast be used over static_cast?何时必须/应该在 static_cast 上使用 dynamic_cast?
【发布时间】:2012-10-01 16:32:01
【问题描述】:

我想知道什么时候 dynamic_cast 必须应该在 static_cast 上使用,并附有示例。我读过this SO question,但它并没有真正提供任何具体的例子。我假设大多数示例将涉及多态类类型。目前我知道在 static_cast 上使用 dynamic_cast 的唯一原因是如果我不能 100% 确定我正在使用的具体类型。

其他一些想法:

  • 横向转换(在多重继承中)
  • 在虚拟继承层次结构中转换为基类
  • 在使用多重继承的类中强制转换为“最右边”的继承类型时,指针是否会改变(如果使用 static_cast)?

“如果类型未知”的原因是唯一的原因吗?如果没有,有人可以提供示例来说明为什么必须或应该使用 dynamic_cast 而不是 static_cast?

【问题讨论】:

  • AFAIK dynamic_cast 用于从基类转换为派生类,并且基类必须至少具有一个虚函数。在几乎所有其他情况下,您都需要static_cast

标签: c++ casting


【解决方案1】:

一般来说,你应该使用dynamic_cast 等级制度,无所谓。一个可能的例外是从 派生类到基类(当然是指针或引用)。否则, 您在层次结构中使用 static_cast 的唯一时间是 分析人员说你必须这样做。

static_cast 在转换为void* 或从void* 转换时更常使用, 或确保空指针常量的正确类型,或 不涉及指针或引用的转换(例如 static_cast<double>( someInt ))。

【讨论】:

  • "static_cast 在转换为 void* 或从 void* 转换时更常使用" -- 尽管 dynamic_cast<void*> 有其自身的含义。因此,决定使用哪个演员阵容的并不是您要转换为 void* 的事实,而是您想要的结果。
  • static_cast 如何验证从void* 到其他类型的转换的有效性? void* 没有静态类型信息(除了它是一个指针)。
  • @SteveJessop 你能解释一下不同之处吗?
  • @RobertDailey:它不验证有效性,除了在void* 和任何指向对象类型之间的所有转换的略高于语法级别的规则之外有效的。而static_cast<void*>dynamic_cast<void*> 之间的区别在于,当应用于多态层次结构中的指向基类的指针时,前者返回的地址与您传入的地址相同,而后者则返回最-您有一个指向基类的指针的派生对象。它很少有用,但它就在那里......
  • "it" 是 static_cast,是的,我是这么说的。 static_cast 的目的之一是它可以反转任何隐式转换。从MyClass*void* 的隐式转换,以及从void*MyClass*static_cast 的隐式转换。
【解决方案2】:

即使您知道动态类型也必须使用dynamic_cast 的一种情况是从 虚拟 基转换为派生更多的类型:

struct A { };
struct B : virtual A { };
struct C : virtual A { };
struct D : B, C { };

A * p = new D;
D * q = dynamic_cast<D*>(p);

原因当然是虚拟库只在运行时确定。

dynamic_cast 的另一个用途是通过casting to void* 发现派生最多的对象的地址,尽管这是否是必要的语言功能尚不完全清楚。 (我设法con­trive a use case,但主要是学术性的。)

【讨论】:

    猜你喜欢
    • 2010-09-24
    • 1970-01-01
    • 2011-06-06
    • 1970-01-01
    • 2010-11-18
    • 2014-05-29
    • 1970-01-01
    相关资源
    最近更新 更多