C++多虚拟继承与COM

Ada*_*dam 6 c++ com multiple-inheritance virtual-inheritance

网上满是"可怕的钻石问题"的解释.StackOverflow也是如此.我想我明白这一点,但我没有将这些知识转化为理解类似但不同的东西.

我的问题始于一个纯粹的C++问题,但答案很可能转移到MS-COM细节中.一般问题是:

class Base { /* pure virtual stuff */ };
class Der1 : Base /* Non-virtual! */ { /* pure virtual stuff */ };
class Der2 : Base /* Non-virtual! */ { /* pure virtual stuff */ };
class Join : virtual Der1, virtual Der2 { /* implementation stuff */ };
class Join2 : Join { /* more implementation stuff + overides */ };
Run Code Online (Sandbox Code Playgroud)

不是经典的钻石解决方案.究竟"虚拟"在这里做什么?

我真正的问题是试图理解我们朋友在CodeProject上讨论.它涉及一个自定义类,用于为Flash播放器创建透明容器.

我以为我会尝试这个地方的乐趣.事实证明,以下声明使您的应用程序崩溃,其中包含Flash播放器的第10版.

class FlashContainerWnd:   virtual public IOleClientSite,
                           virtual public IOleInPlaceSiteWindowless,
                           virtual public IOleInPlaceFrame,
                           virtual public IStorage
Run Code Online (Sandbox Code Playgroud)

调试显示,当从不同的调用者进入函数实现(QueryInterface等)时,我得到不同调用的不同"this" - 指针值.但删除"虚拟"就可以了!没有崩溃,同样"这个" - 指针.

我想清楚地了解到底发生了什么.非常感谢.

干杯亚当

Rob*_*ker 2

认为您的 COM 示例的问题在于,通过添加 virtual 关键字,您是在说所有 IOle* 接口共享一个通用的 IUnknown 实现。为了实现这一点,编译器必须创建多个 v 表,因此根据派生类的不同,您可以使用不同的“this”值。

COM 要求当您在 IUnknown 对象上调用 IQueryInterface 时,该对象公开的所有接口都返回相同的值IUnknown ...此实现显然破坏了这一点。

如果没有虚拟继承,每个 IOle* 名义上都有自己的 IUnknown 实现。然而,由于 IUnknown 是一个抽象类,并且没有任何存储编译器,并且所有 IUnknown 实现都来自 FlashContainerWnd,因此只有一个实现。

(好吧,所以最后一点听起来很弱......也许对语言规则有更好掌握的人可以解释得更清楚)