C++ 通过QI或继承实现IUnknown平等的差异
我感兴趣的是比较两个C++ 通过QI或继承实现IUnknown平等的差异,c++,pointers,com,C++,Pointers,Com,我感兴趣的是比较两个IDirect3DDevice9COM指针,它们继承IUnknown,以获得相等性。根据a,我知道您可以对两个指针执行QIIUnknown,并比较结果是否相等。然而,我很好奇,我们是否可以通过一个直接接受两个IUnknown指针的IsEqual方法来完成同样的事情,让继承确定相关的IUnknown指针,并将其用于相等性检查。根据我的实验,这似乎有效,并且不需要QI和release操作(或者可能是隐式操作)。如果有任何警告说明这个建议无效,请告诉我 BOOL IsEqual(I
IDirect3DDevice9
COM指针,它们继承IUnknown
,以获得相等性。根据a,我知道您可以对两个指针执行QIIUnknown
,并比较结果是否相等。然而,我很好奇,我们是否可以通过一个直接接受两个IUnknown
指针的IsEqual
方法来完成同样的事情,让继承确定相关的IUnknown
指针,并将其用于相等性检查。根据我的实验,这似乎有效,并且不需要QI
和release
操作(或者可能是隐式操作)。如果有任何警告说明这个建议无效,请告诉我
BOOL IsEqual(IUnknown *pA, IUnknown *pB)
{
return (pA == pB);
}
BOOL IsEqual (IDirect3DDevice9 *pDevice1, IDirect3DDevice9 *pDevice2)
{
IUnknown *u1, *u2;
pDevice1->QueryInterface(IID_IUnknown, &u1);
pDevice2->QueryInterface(IID_IUnknown, &u2);
BOOL areSame = u1 == u2;
u1->Release();
u2->Release();
return areSame;
}
下面是一些具有多重继承的示例代码。这里,
IUnknown
在层次结构中发生两次,但任何其他接口也可能发生两次
我使用的不是VisualC++的特性,因此这个代码更容易在在线编译器服务上尝试。
#include <stdio.h>
class IUnknown {};
class IInterface1 : public IUnknown {};
class IInterface2 : public IUnknown {};
class Class : public IInterface1, public IInterface2 {};
int main() {
Class object;
// Please note that only implicit conversions are used -
// exactly as if you were passing Derived* pointers into
// a function that accepts Base* pointers
IInterface1* interface1 = &object;
IUnknown* unknown1 = interface1;
IInterface2* interface2 = &object;
IUnknown* unknown2 = interface2;
printf( "%p %p %s", unknown1, unknown2,
(unknown1 == unknown2) ? "true" : "false");
}
因为转换是不明确的。只有告诉您要使用哪个继承路径,代码才会编译。一旦您选择了路径,您可能会得到相同基类的不同子对象,这些子对象当然位于不同的地址。实际上,我考虑了更多的情况,我认为第一个IsEqual检查不能保证按预期工作,因为传递到方法中的IUnknown指针只代表铸造的相同IDirect3DDevice9指针。因此,如果开始时两个指针不同,则相等性检查将失败。否,编译器不知道如何调用QueryInterface()。它将假定指针已经兼容,因为IUnknown是基本接口,并且不会尝试转换它。如果产生错误的结果,则需要QI。您可以使用C++中的CCOMQIPTR类来处理QI调用和ReleSever()调用。如果所有COM组件都实现为具有多继承和聚合的C++类,那么这可能是可行的,但情况并非如此。事实上,COM教程示例建议在嵌套类中实现接口,这使得聚合支持更容易。这使得对IUnknown的查询成为强制性的。您真正想要回答的问题是:“这两个指针相等”还是“这两个指针是由同一个对象实现的”?如果是前者,那么是的,只需将它们与
==
进行比较;但目前还不清楚这个答案对什么有用。如果是后者,则需要比较COM标识(定义为通过专门查询IID\u IUnknown
而获得的“IUnknown
指针),因为单个对象通常实现多个接口,因此具有多个IUnknown
实现。另请参见:CComPtr::IsEqualObject
IUnknown* unknown = &object;//WON'T COMPILE