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.
除了回滚到普通继承之外,还有其他解决方案吗?
我不认为你可以指望任何构建的类在编译器之间兼容.Borland声称他们可以加载和与MSVC构建的类进行互操作.如果是这样,看起来他们有一个bug.据我所知,关于VTable的确切结构的任何内容都不在C++的规范中,因此预计不会在编译器之间起作用.
与C不同,C++没有交叉编译器ABI - 编译器可以任意方式自由地实现虚拟继承(甚至是普通继承).
结果是:在编译器之间调用C++函数并不能保证工作.我知道它很难看,但是如果你想让你的DLL与多个编译器愉快地交互,你可能更好地提供一组普通extern "C"函数和手动构建的函数指针表.
注意:支持构建COM对象(或有选项)的编译器在其对象布局中受到更多限制.(我知道最近版本的MSVC++生成符合COM的对象,至少在大多数情况下 - 不确定是否覆盖了虚拟继承.)
dil*_*ig0 -2
可能不会回答你的问题......但强烈建议不要像你一样使用多重继承(称为“可怕的钻石”)。