www.pudn.com > COM技术内幕配书源码.rar > REFCOUNT.CPP
// // RefCount.cpp // To compile, use: cl RefCount.cpp UUID.lib // #include#include void trace(const char* msg) { cout << msg << endl ;} // Forward references for GUIDs extern const IID IID_IX ; extern const IID IID_IY ; extern const IID IID_IZ ; // Interfaces interface IX : IUnknown { virtual void __stdcall Fx() = 0 ; } ; interface IY : IUnknown { virtual void __stdcall Fy() = 0 ; } ; interface IZ : IUnknown { virtual void __stdcall Fz() = 0 ; } ; // // Component // class CA : public IX, public IY { // IUnknown implementation virtual HRESULT __stdcall QueryInterface(const IID& iid, void** ppv) ; virtual ULONG __stdcall AddRef() ; virtual ULONG __stdcall Release() ; // Interface IX implementation virtual void __stdcall Fx() { cout << "Fx" << endl ;} // Interface IY implementation virtual void __stdcall Fy() { cout << "Fy" << endl ;} public: // Constructor CA() : m_cRef(0) {} // Destructor ~CA() { trace("CA: Destroy self.") ;} private: long m_cRef; } ; HRESULT __stdcall CA::QueryInterface(const IID& iid, void** ppv) { if (iid == IID_IUnknown) { trace("CA QI: Return pointer to IUnknown.") ; *ppv = static_cast (this) ; } else if (iid == IID_IX) { trace("CA QI: Return pointer to IX.") ; *ppv = static_cast (this) ; } else if (iid == IID_IY) { trace("CA QI: Return pointer to IY.") ; *ppv = static_cast (this) ; } else { trace("CA QI: Interface not supported.") ; *ppv = NULL ; return E_NOINTERFACE; } reinterpret_cast (*ppv)->AddRef() ; return S_OK ; } ULONG __stdcall CA::AddRef() { cout << "CA: AddRef = " << m_cRef+1 << '.' << endl ; return InterlockedIncrement(&m_cRef) ; } ULONG __stdcall CA::Release() { cout << "CA: Release = " << m_cRef-1 << '.' << endl ; if (InterlockedDecrement(&m_cRef) == 0) { delete this ; return 0 ; } return m_cRef ; } // // Creation function // IUnknown* CreateInstance() { IUnknown* pI = static_cast (new CA) ; pI->AddRef() ; return pI ; } // // IIDs // // {32bb8320-b41b-11cf-a6bb-0080c7b2d682} static const IID IID_IX = {0x32bb8320, 0xb41b, 0x11cf, {0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}} ; // {32bb8321-b41b-11cf-a6bb-0080c7b2d682} static const IID IID_IY = {0x32bb8321, 0xb41b, 0x11cf, {0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}} ; // {32bb8322-b41b-11cf-a6bb-0080c7b2d682} static const IID IID_IZ = {0x32bb8322, 0xb41b, 0x11cf, {0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}} ; // // Client // int main() { HRESULT hr ; trace("Client: Get an IUnknown pointer.") ; IUnknown* pIUnknown = CreateInstance() ; trace("Client: Get interface IX.") ; IX* pIX = NULL ; hr = pIUnknown->QueryInterface(IID_IX, (void**)&pIX) ; if (SUCCEEDED(hr)) { trace("Client: Succeeded getting IX.") ; pIX->Fx() ; // Use interface IX. pIX->Release() ; } trace("Client: Get interface IY.") ; IY* pIY = NULL ; hr = pIUnknown->QueryInterface(IID_IY, (void**)&pIY) ; if (SUCCEEDED(hr)) { trace("Client: Succeeded getting IY.") ; pIY->Fy() ; // Use interface IY. pIY->Release() ; } trace("Client: Ask for an unsupported interface.") ; IZ* pIZ = NULL ; hr = pIUnknown->QueryInterface(IID_IZ, (void**)&pIZ) ; if (SUCCEEDED(hr)) { trace("Client: Succeeded in getting interface IZ.") ; pIZ->Fz() ; pIZ->Release() ; } else { trace("Client: Could not get interface IZ.") ; } trace("Client: Release IUnknown interface.") ; pIUnknown->Release() ; return 0; }