有什么理由反对在QueryInterface()实现中直接调用AddRef()吗? 当在C++中实现 IUn::QueIdIsFrEffice()/Cuff>时,指针操作有几个注意事项。例如,当类实现多个接口(多重继承)时: 类CMyClass:public IInterface1,public IInterface2{ }; //内部CMyClass::QueryInterface(): 如果(iid==(IUnknown)){ *ppv=static_cast(this);//为正确调整指针而向上投射 //调用Addref(),返回S_OK }

有什么理由反对在QueryInterface()实现中直接调用AddRef()吗? 当在C++中实现 IUn::QueIdIsFrEffice()/Cuff>时,指针操作有几个注意事项。例如,当类实现多个接口(多重继承)时: 类CMyClass:public IInterface1,public IInterface2{ }; //内部CMyClass::QueryInterface(): 如果(iid==(IUnknown)){ *ppv=static_cast(this);//为正确调整指针而向上投射 //调用Addref(),返回S_OK },c++,visual-c++,com,interop,com-interop,C++,Visual C++,Com,Interop,Com Interop,在多继承场景中,向上转换的原因非常清楚。然而,我也不时看到以下情况: static_cast<IUnknown*>( *ppv )->AddRef(); static_cast(*ppv)->AddRef(); 而不是简单地从QueryInterface()实现内部调用AddRef() 有什么理由我应该对先前复制到ppv中的值进行强制转换,而不是对当前对象调用AddRef()?AddRef在IUnknown中是纯虚拟的,其他接口都没有实现它,因此,程序中唯一的实现就是在CM

在多继承场景中,向上转换的原因非常清楚。然而,我也不时看到以下情况:

static_cast<IUnknown*>( *ppv )->AddRef();
static_cast(*ppv)->AddRef();
而不是简单地从
QueryInterface()
实现内部调用
AddRef()


有什么理由我应该对先前复制到
ppv
中的值进行强制转换,而不是对当前对象调用
AddRef()

AddRef
IUnknown
中是纯虚拟的,其他接口都没有实现它,因此,程序中唯一的实现就是在
CMyClass
中编写的实现。这一方法覆盖了
IInterface1::AddRef
IInterface2::AddRef
IUnknown
没有任何数据成员(例如引用计数),因此菱形问题不会导致类容易受到问题的影响,例如对
AddRef
的不同调用作用于同一类中的不同数据


this->AddRef()
的调用将被路由到与
static\u cast(*ppv)->AddRef()
相同的位置。我认为没有理由使用更详细的样式。

使用详细语法的原因可能在于,不仅
可能会在
ppv
中返回,这在较长的
if else if
中很容易被忽略。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;
}
STDMETHODIMP-Car::IternalQueryInterface(refid-riid,void**ppv){
如果(riid==IID_IUnknown)
*ppv=静态强制转换(&m\U innerUnknown);
else if(riid==IID_ivichle)
*ppv=静态施法(本);
否则如果(riid==IID_ICar)
*ppv=静态施法(本);
其他的
返回(*ppv=0),无界面;
((IUnknown*)*ppv)->AddRef();
返回S_OK;
}

您是否可以发布IUnknown类的定义?@hype:当然可以。
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;
}