Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 通过QI或继承实现IUnknown平等的差异_C++_Pointers_Com - Fatal编程技术网

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,我知道您可以对两个指针执行QI
IUnknown
,并比较结果是否相等。然而,我很好奇,我们是否可以通过一个直接接受两个
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