在我这里的一个项目中,我有一个实现了四个接口(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 风格转换。
编辑 试图重现问题但不能,文件可以在
上找到- class2.hpp : http://pastebin.com/CBVykqcD
- class2.cpp : http://pastebin.com/Vy2YsEGP
- 类.cpp:http://pastebin.com/wwHpe87g
在 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/