5

我一直在阅读该站点上的其他一些线程,它们提到了 dynamic_cast 和 static_cast 对向上转换都是安全的。

为什么这些甚至需要向上转换?

例如,如果类 B 派生自 A,则

A * ptr = new B ();

仍然可以工作,并且表现得像 A 类型的对象。(我也来自 Java 背景,不需要向上转换的转换。

我还在这个网站上读到,向下转换不需要 dynamic_cast [有问题的“什么时候应该使用 static_cast、dynamic_cast、const_cast 和 reinterpret_cast? ”]。同样,我认为只有在向下转换时才真正需要转换,因为向上转换会自动发生。

我哪里错了?

4

3 回答 3

3

如果您有复杂的继承层次结构,则默认向上转换行为可能不起作用。考虑例如:

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

在该层次结构中,类型对象D有两个不同的类型基础A。从D*to的转换A*是模棱两可的。对于这种情况,您可以强制执行中间步骤

A *p = static_cast<B*>(d);   // Give me the 'A' subobject within 'B'

类似地,如果有一个函数具有多个重载,可以采用基类型或派生类型,并且您需要调用采用基类型的版本(注意:这里有代码味道!),那么您可以使用强制转换来指导重载决策。同样,如果您需要直接解决重载问题,那么您可能做错了其他事情。

除了极端情况(即默认向上转换不起作用时),实际上没有理由明确使用强制转换操作,我实际上建议反对它,因为强制转换应该是一个警告灯,过度使用它们可能会使它们正常而不是读取代码时发出警报。

于 2013-04-29T18:56:53.277 回答
1

在多重继承的情况下(Java 并不真正拥有),您可能会调整“this”指针。在那种情况下, reinterpret_cast 是不安全的,这就是他们试图通过说 static_cast 和 dynamic_cast 是安全的来强调的。

顺便说一句,在对要移植到 Android-without-dynamic_cast 的代码库的调查中,我发现了 127 个 dynamic_cast,其中 122 个实际上是不必要的。这是由非常精通 C++ 的人编写的代码。

于 2013-04-29T18:55:09.633 回答
0

为什么这些甚至需要向上转换?

它们不是,并且将它们用于向上转换是(恕我直言)误导:出于某种原因不需要转换:从逻辑上讲,子类对象是超类的实例。

总之,我不鼓励明确的向上转型。对于坚持我至少要求一致性的人:在任何地方都使用显式向上转换,包括在初始化中:

A * ptr{static_cast<A*>(new B)};

大多数人会同意这只是愚蠢的。

于 2013-04-29T18:54:44.110 回答