08/01/28 01:31:57
>>530
要は、本来Bでオーバーライドする必要のない関数も、B内から手動でAの実装を呼ぶようにすればいい。
インタフェースはメンバ変数ないから、キャスト関係くらいしか仮想継承の有無の違いはないといっても過言ではない。
struct IA : IUnknown {virtual HRESULT STDMETHODCALLTYPE FnA() = 0;};
struct A : IA {
virtual HRESULT STDMETHODCALLTYPE QueryInterface(IID&, void**) {/*実装*/}
virtual ULONG STDMETHODCALLTYPE AddRef() {/*実装*/}
virtual ULONG STDMETHODCALLTYPE Release() {/*実装*/}
virtual HRESULT STDMETHODCALLTYPE FnA() {/*実装*/}
};
struct IB : IA {virtual HRESULT STDMETHODCALLTYPE FnB() = 0;};
struct B : A, IB {
virtual HRESULT STDMETHODCALLTYPE QueryInterface(IID&, void**);
virtual ULONG STDMETHODCALLTYPE AddRef() {return A::AddRef();}
virtual ULONG STDMETHODCALLTYPE Release() {return A::Release();}
virtual HRESULT STDMETHODCALLTYPE FnA() {return A::FnA();} //オーバーライドしない気なら
virtual HRESULT STDMETHODCALLTYPE FnB() {/*実装*/}
};
HRESULT STDMETHODCALLTYPE B::QueryInterface(IID& riid, void** ppv) {
if (ppv == 0) {
return E_POINTER;
} else if (riid == IID_B) {
*ppv = static_cast<IB*>(this);
AddRef(); //直接A::AddRef()でも可
return S_OK;
} else {
return A::QueryInterface(riid, ppv);
}
}
Javaのインタフェースの仕様だとBでのAddRef以下のようなことを書く必要がなかった気がする、ちょっとうらやましい。