当您使用多重继承时,静态转换是否安全?

12 c++ dynamic-cast static-cast

我发现自己处于一种我知道什么类型的东西的情况.Type是三个(或更多)继承级别之一.我调用返回的工厂B*但是T是一个类型的最高级别(如果我的代码知道它是什么)或第二级别.

无论如何,我static_cast在模板中做了一个错误的事情.我的问题是我什么时候可以安全地静态施放?有没有这样的时间?我在这种情况下做到了,因为当我意外地将T作为古怪的东西(已经发生并且)动态转换忽略(并返回null)时,我宁愿得到编译错误.但是,当我知道正确的类型时,指针未被调整,导致我有一个错误的指针.我不确定为什么在这种情况下允许静态转换.

我什么时候可以安全地使用static_cast进行向下铸造?有没有情况?现在似乎总是错误地使用a static_cast(当目的是向下投射时)

好的,我想出了如何重现它.

#include <iostream>
struct B { virtual void f1(){} };
struct D1 : B {int a;};
struct D2 : B {int a, b; };
struct DD : D1, D2 {};

int main(){
void* cptr = new DD(); //i pass it through a C interface :(
B*  a = (B*)cptr;
D2* b = static_cast<D2*>(a); //incorrect ptr
D2* c = dynamic_cast<D2*>(a); //correct ptr
std::cout << a << " " <<b << " " <<c;
}
Run Code Online (Sandbox Code Playgroud)

Ben*_*igt 10

交叉投射:

struct Base1 { virtual void f1(); };
struct Base2 { virtual void f2(); };
struct Derived : Base1, Base2 {};

Base1* b1 = new Derived();
Base2* b2 = dynamic_cast<Base2*>(b1);
Run Code Online (Sandbox Code Playgroud)

需要使用dynamic_cast,它不能用static_cast(static_cast应该导致编译时错误). dynamic_cast如果任何一个基类不是多态的(虚函数的存在不是可选的),它也会失败.

请参阅MSDN上的此说明


Che*_*Alf 5

如果Derived具有Base作为公共(或以其他方式可访问)的基类,并且d类型为Derived*static_cast<Base*>(d) 则为向上转换

这在技术上总是安全的。

并且通常是不必要的,除非您隐藏(隐藏)方法。

干杯 & hth.,

  • @acidzombie24:抱歉,您所描述的不是交叉转换。交叉转换是当你从 `Base1` 到 `Base2` 的 `dynamic_cast` 时,给定一个实际上继承了 `Base1` 和 `Base2` 的对象,但是 `Base1` 和 `Base2` 本身并不相关。但是 Alf 关于向上转换是绝对正确的。我认为您不是要询问向上倾斜,而是向下倾斜。 (2认同)
  • @acidzombie24:进一步阅读您的问题表明您可能在谈论交叉转换(实际上是向下转换,然后是向上转换)并且没有很好地解释它。您确实需要至少提供一个精炼的示例来说明您的意思,即使它不是您的实际代码。 (2认同)