是否有任何理由反对在 QueryInterface() 实现中直接调用 AddRef() ?
在 C++ 中实现 IUnknown::QueryInterface() 时,有一些关于指针操作的注意事项。例如,当类实现多个接口(多重继承)显式向上转换是必要的:
class CMyClass : public IInterface1, public IInterface2 {
};
//inside CMyClass::QueryInterface():
if( iid == __uuidof( IUnknown ) ) {
*ppv = static_cast<IInterface1*>( this ); // upcast in order to properly adjust the pointer
//call Addref(), return S_OK
}
在多重继承场景中,向上转换的原因非常清楚。然而,我也时不时地看到以下内容:
static_cast<IUnknown*>( *ppv )->AddRef();
而不是简单地从 QueryInterface()
实现内部调用 AddRef()
。
我是否应该对之前复制到 ppv 中的值进行转换,而不是仅仅在当前对象上调用 AddRef() ?
When implementing IUnknown::QueryInterface()
in C++ there're several caveats with pointers manipulation. For example, when the class implements several interfaces (multiple inheritance) explicit upcasts are necessary:
class CMyClass : public IInterface1, public IInterface2 {
};
//inside CMyClass::QueryInterface():
if( iid == __uuidof( IUnknown ) ) {
*ppv = static_cast<IInterface1*>( this ); // upcast in order to properly adjust the pointer
//call Addref(), return S_OK
}
The reason for upcast is quite clear in multiple inheritance scenarios. However every here and there I also see the following:
static_cast<IUnknown*>( *ppv )->AddRef();
instead of simply invoking AddRef()
from inside QueryInterface()
implementation.
Is there any reason I should do the cast of the value previously copied into ppv
instead of just calling AddRef()
on the current object?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
AddRef
在IUnknown
中是纯虚拟的,其他接口都没有实现它,因此程序中唯一的实现就是您在CMyClass
中编写的实现>。该方法会覆盖 IInterface1::AddRef 和IInterface2::AddRef
两者。IUnknown
没有任何数据成员(例如引用计数),因此菱形问题不会导致您的类容易受到诸如对AddRef 作用于同一类中的不同数据。
对
this->AddRef()
的调用将被路由到与static_cast(*ppv)->AddRef()
相同的位置。我认为没有理由采用更冗长的风格。AddRef
is pure virtual inIUnknown
, and none of the other interfaces implement it, so the only implementation in your program is the one you write inCMyClass
. That one method overrides bothIInterface1::AddRef
andIInterface2::AddRef
.IUnknown
doesn't have any data members (such as a reference count), so the diamond problem doesn't cause your class to be susceptible to a problem such as different calls toAddRef
acting on different data in the same class.Calls to
this->AddRef()
are going to be routed to the same place asstatic_cast<IUnknown*>(*ppv)->AddRef()
. I see no reason for the more verbose style.语法冗长的原因可能在于
ppv
中不仅可能返回this
,这在较长的if-else- 中很容易被忽视 -如果
。来自 Don Box 的 Essential COM 的示例:The reason for the verbose syntax probably lies in the fact that not only
this
might be returned inppv
, which is easy to overlook in a longerif-else-if
. An example from Don Box's Essential COM: