不同的编译器的C++虚拟继承实现不兼容吗?

5 c++ c++builder virtual-inheritance visual-c++

我有这样的公共接口层次结构:

struct ISwitchable {
    /* Obtain pointer to another implemented interface of the same instance. */
    virtual int switch(unsigned int interfaceId, void** pInstance) = 0;
};
struct IFoo : public ISwitchable { /* Methods */ };
struct IBar : public ISwitchable { /* Methods */ };
struct IFooBar : public IFoo, public IBar { /* Methods */ };
Run Code Online (Sandbox Code Playgroud)

实现IFooBar的类与工厂函数一起放入dll.客户端代码加载dll,使用工厂函数创建类实例并根据接口使用它们(它们作为头文件提供).

Scheme使用MSVC制作的dll和Borland C++ Builder 6制作的客户端代码可以正常工作.

我将虚拟继承引入层次结构:

struct IFoo : public virtual ISwitchable { /* Methods */ };
struct IBar : public virtual ISwitchable { /* Methods */ };
Run Code Online (Sandbox Code Playgroud)

而在相同的情况下(由MSVC的dll,客户端由Builder)客户端代码请求类的实例,他得到它与凌乱的vtable.

除了回滚到普通继承之外,还有其他解决方案吗?

Lou*_*nco 8

我不认为你可以指望任何构建的类在编译器之间兼容.Borland声称他们可以加载和与MSVC构建的类进行互操作.如果是这样,看起来他们有一个bug.据我所知,关于VTable的确切结构的任何内容都不在C++的规范中,因此预计不会在编译器之间起作用.


j_r*_*ker 7

与C不同,C++没有交叉编译器ABI - 编译器可以任意方式自由地实现虚拟继承(甚至是普通继承).

结果是:在编译器之间调用C++函数并不能保证工作.我知道它很难看,但是如果你想让你的DLL与多个编译器愉快地交互,你可能更好地提供一组普通extern "C"函数和手动构建的函数指针表.

注意:支持构建COM对象(或有选项)的编译器在其对象布局中受到更多限制.(我知道最近版本的MSVC++生成符合COM的对象,至少在大多数情况下 - 不确定是否覆盖了虚拟继承.)

  • 绝对有一个用于C++的交叉编译器ABI,即Itanium.我认为它的变体被其他CPU上的多个编译器使用. (2认同)

dil*_*ig0 -2

可能不会回答你的问题......但强烈建议不要像你一样使用多重继承(称为“可怕的钻石”)。

  • 为什么不?看看什么是多重继承:Java 接口的 C++ 等价物。应该是安全的。 (3认同)