我一直在阅读本网站上的其他一些帖子,他们提到了dynamic_cast和static_cast对于向上转播是否安全。
为什么这些甚至需要上传?
例如,如果B类派生自A,那么
A * ptr = new B ();
仍然有效,并且表现得像A类型的对象。(我也是来自Java背景,不需要转换转发。
我也在这个网站上看到,向下转发不需要dynamic_cast [问题“When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?”] 。再一次,我认为只有当你进行向下转换时才能进行转换,因为自动进行向上转换。
我哪里错了?
答案 0 :(得分:3)
如果您具有复杂的继承层次结构,则默认的向上转换行为可能不起作用。考虑例如:
struct A {};
struct B : A {};
struct C : A {};
struct D : B, C {};
在该层次结构中,D
类型的对象具有两个不同类型A
的基础。从D*
到A*
的转换不明确。对于这种情况,您可以强制执行中间步骤
A *p = static_cast<B*>(d); // Give me the 'A' subobject within 'B'
类似地,如果有一个具有多个重载的函数可以采用基类型或派生类型,并且您需要调用采用基类型的版本(注意:代码闻到这里!)然后您可以使用强制转换直接超载分辨率。同样,如果您需要直接重载解析,那么您可能正在做其他错误。
除了极端情况(即默认的upcast不起作用)时,实际上没有理由明确使用强制转换操作,我实际上会建议反对它,因为强制转换应该是一个警告灯并且过度使用它们可能会使它们成为可能正常,并且在阅读代码时不会发出警报。
答案 1 :(得分:1)
如果存在多重继承(Java实际上没有),您可能会调整“this”指针。在这种情况下,reinterpret_cast是不安全的,这是他们试图通过说static_cast和dynamic_cast是安全的强调。
作为一个小小的注释,在一个代码库的调查中,我将发现127个dynamic_casts,其中122个实际上并不是必需的。这是由人们编写的代码,可以非常精通C ++。
答案 2 :(得分:0)
为什么这些甚至需要上传?
它们不是,并且将它们用于upcasts是(恕我直言)误导:不需要强制转换出于某种原因:逻辑上,子类对象是 - 超类的一个实例。
总之,我会劝阻明确的向上翻译。对于坚持这一点的人,我至少要求一致性:在所有地方使用显式向上,包括初始化:
A * ptr{static_cast<A*>(new B)};
大多数人会同意这很愚蠢。