c++ - C 样式转换导致 SIGILL,dynamic_cast ok

标签 c++ g++

在我这里的一个项目中,我有一个实现了四个接口(interface)的类:

class A : public B,
          public C,
          public D,
          public E
{
  ----Implementation Code here----
};

这四个接口(interface)只包含纯虚函数,它们都没有构成菱形问题(所以我不需要使用 virtual 关键字)所以我在做这样的事情时没有问题:

A* var = new A;
((C*)var)->method_from_interface();

然而,一些丑陋的事情正在发生,因为该函数正在跳转到 A 类的另一个方法,并且 valgrind 提示未处理的指令。但是,这样做:

 A* var = new A;
(dynamic_cast<C*>(var))->method_from_interface();

工作正常。

所以我想知道这是 G++ 错误还是语言误用?

编辑:

也许我把我的问题简化了太多。我在函数调用中将 A 类作为 D* 接收:

void do_something(provider* p) {
   D* iface = p->recoverItemByName("nameThatReturnsClassA");
   ((B*) iface)->call_method_from_b_iface();
}

请注意,我知道此时 D* 实际上是 A*,因此对 B* 进行强制转换并没有违反任何规则。不过,我不能对其进行 static_cast,因为 D* 和 B* 没有关系,但我可以成功使用 reinterpret_cast。

最佳答案

C 风格的转换只是将您的指针“基本”映射到您的类。如果你的方法在你的类中是 offset=42,它会使 (*(A+42)) ()(当然是简化的)。

但是,如果继承自多个类,则必须考虑编译器放置它们的各种类和顺序。

static_cast 正在考虑多重继承。

在您的示例中,它可能适用于 B、C、D 或 E,但不适用于其他。但是,您没有充分的理由这样做:您可以调用 A->methodFromInterface(),它就可以正常工作!

在 C++ 上,建议使用 static_cast 或 dynamic_cast(注意:第二个依赖于 rtti,它可能不可用)并丢弃旧的 C 风格转换。

编辑 试图重现问题但不能,文件可以在

上找到

在 MacOs 10.6 上编译:

g++ -fno-rtti -o truc ./class.cpp ./class2.cpp && ./truc

关于c++ - C 样式转换导致 SIGILL,dynamic_cast ok,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8169913/

相关文章:

c++ - 关联两个变量一起改变

C++,成员地址

c++ - 成员初始化列表错误中的模板基构造函数调用

c++ - "to_string"是 't a member of "标准”?

linux - 在 Linux 上使用静态链接构建应用程序是否明智?

c++ - 如何将字符串转换为十六进制?

c++ - 为什么我们必须在箭头符号( -> )之后再次指定数据类型

c++ - 有什么办法可以优化这个功能吗?

c++ - 使用 gcov 测试 C++ 程序

linux - 无法升级 gcc/g++ 版本?