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" - 指针值.但删除"虚拟"就可以了!没有崩溃,同样"这个" - 指针.
我想清楚地了解到底发生了什么.非常感谢.
干杯亚当
我认为您的 COM 示例的问题在于,通过添加 virtual 关键字,您是在说所有 IOle* 接口共享一个通用的 IUnknown 实现。为了实现这一点,编译器必须创建多个 v 表,因此根据派生类的不同,您可以使用不同的“this”值。
COM 要求当您在 IUnknown 对象上调用 IQueryInterface 时,该对象公开的所有接口都返回相同的值IUnknown ...此实现显然破坏了这一点。
如果没有虚拟继承,每个 IOle* 名义上都有自己的 IUnknown 实现。然而,由于 IUnknown 是一个抽象类,并且没有任何存储编译器,并且所有 IUnknown 实现都来自 FlashContainerWnd,因此只有一个实现。
(好吧,所以最后一点听起来很弱......也许对语言规则有更好掌握的人可以解释得更清楚)