是否有任何理由反对在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 
} 
在多继承场景中,upcast的原因非常清楚。然而,每次在这里和那里我也看到以下内容:
static_cast<IUnknown*>( *ppv )->AddRef();
而不是简单地从
QueryInterface()
实现内部调用
AddRef()
。 有什么理由我应该将之前复制到
ppv
中的值转换为而不是仅仅在当前对象上调用
AddRef()
?     
已邀请:
AddRef
IUnknown
中是纯虚拟的,并且没有其他接口实现它,因此程序中唯一的实现是你在
CMyClass
中编写的。那一种方法会覆盖
IInterface1::AddRef
IInterface2::AddRef
IUnknown
没有任何数据成员(例如引用计数),因此菱形问题不会导致您的类容易出现问题,例如对同一类中的不同数据执行不同的调用。 拨打
this->AddRef()
的电话将被发送到与
static_cast<IUnknown*>(*ppv)->AddRef()
相同的地方。我认为没有理由采用更冗长的风格。     
冗长语法的原因可能在于,不仅ѭѭ可能会在
ppv
中返回,这在很长的时间内很容易被忽略。 Don Box的Essential COM的一个例子:
STDMETHODIMP Car::IternalQueryInterface(REFIID riid, void **ppv) {
    if (riid == IID_IUnknown)
        *ppv = static_cast<IUnknown*>(&m_innerUnknown);
    else if (riid == IID_IVehicle)
        *ppv = static_cast<IVehicle*>(this);
    else if (riid == IID_ICar)
        *ppv = static_cast<ICar*>(this);
    else
        return (*ppv = 0), E_NOINTERFACE;
    ((IUnknown*)*ppv)->AddRef();
    return S_OK;
}
    

要回复问题请先登录注册