问题描述
假设我的COM对象实现了两个或多个COM接口:
class CMyClass:public IPersistFile,public IPersistStream {
};
在实现QueryInterface()时,我需要能够返回一个IUnknown *指针。因为两个基本接口都派生自IUnknown我不能隐式隐式 - 这样的上传将是暧昧的。明确地说,我需要使用以下两种方法之一:
if(iid == __uuidof(IUnknown)){
* ppv = static_cast< IPersistFile *>(this);
static_cast< IPersistFile *>(this) - > AddRef();
return S_OK;
}
或
if(iid == __uuidof(IUnknown)){
* ppv = static_cast< IPersistStream *>(this);
static_cast< IPersistStream *>(this) - > AddRef();
return S_OK;
}
看起来像唯一的要求是每当QI
我应该选择哪个向上转换,为什么?
Mark Ransom已经给出了正确的答案 - 任何事情都会做,只要它是一致的 - 但挑选第一个有一个小的优势。由于布局规则,第一个接口的 IUnknown *
将指向对象的开始。任何其他 IUnknown *
将指向对象中其他位置的后续vtable指针。为了调试的目的,知道ano对象在内存中开始的位置非常有用。 Suppose my COM object implements two or more COM interfaces:
class CMyClass : public IPersistFile, public IPersistStream {
};
when implementing QueryInterface() I need to be able to return an IUnknown* pointer. Since both base interfaces are derived from IUnknown I cannot upcast implicitly - such upcast would be umbiguous. To upcast explicitly I need to use either of the two ways:
if( iid == __uuidof( IUnknown ) ) {
*ppv = static_cast<IPersistFile*>( this );
static_cast<IPersistFile*>( this )->AddRef();
return S_OK;
}
or
if( iid == __uuidof( IUnknown ) ) {
*ppv = static_cast<IPersistStream*>( this );
static_cast<IPersistStream*>( this )->AddRef();
return S_OK;
}
Looks like the only requirement is that whenever QI() is called on an object it returns the same pointer each time and I meet that requirement if I choose any of the casts and just stick to it.
Which upcast should I choose and why?
Mark Ransom already gave the correct answer - any will do, as long as it's consistent - but picking the first one has one minor advantage. Due to layout rules, the IUnknown*
of the first interface will point to the start of the object. Any other IUnknown*
will point to subsequent vtable pointers elsewhere in the object. For debugging purposes, it's very useful to know where ano object begins in memory.
这篇关于当一次实现几个COM接口,我怎么upcast到IUnknown?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!