None.gif//AddRef和Release的实现
None.gif
#include <iostream>
None.gif
using namespace std;
None.gif#include 
<objbase.h>
None.gif
ExpandedBlockStart.gifContractedBlock.gif
void trace(const char* msg) dot.gif{ cout << msg << endl ;}
None.gif
None.gif
// Forward references for GUIDs
None.gif
extern const IID IID_IX ;
None.gif
extern const IID IID_IY ;
None.gif
extern const IID IID_IZ ;
None.gif
None.gif
// Interfaces
None.gif
interface IX : IUnknown
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    
virtual void __stdcall Fx() = 0 ;
ExpandedBlockEnd.gif}
 ;
None.gif
None.gif
interface IY : IUnknown
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    
virtual void __stdcall Fy() = 0 ;
ExpandedBlockEnd.gif}
 ;
None.gif
None.gif
interface IZ : IUnknown
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    
virtual void __stdcall Fz() = 0 ;
ExpandedBlockEnd.gif}
 ;
None.gif
None.gif
None.gif
//
None.gif
// Component
None.gif
//
None.gif
class CA : public IX,
None.gif           
public IY
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    
// IUnknown implementation
InBlock.gif
    virtual HRESULT __stdcall QueryInterface(const IID& iid, void** ppv) ;            
InBlock.gif    
virtual ULONG __stdcall AddRef() ;
InBlock.gif    
virtual ULONG __stdcall Release() ;
InBlock.gif
InBlock.gif    
// Interface IX implementation
ExpandedSubBlockStart.gifContractedSubBlock.gif
    virtual void __stdcall Fx() dot.gif{ cout << "Fx" << endl ;}
InBlock.gif
InBlock.gif    
// Interface IY implementation
ExpandedSubBlockStart.gifContractedSubBlock.gif
    virtual void __stdcall Fy() dot.gif{ cout << "Fy" << endl ;}
InBlock.gif
InBlock.gif
public:
InBlock.gif    
// Constructor
ExpandedSubBlockStart.gifContractedSubBlock.gif
    CA() : m_cRef(0dot.gif{}
InBlock.gif
InBlock.gif    
// Destructor
ExpandedSubBlockStart.gifContractedSubBlock.gif
    ~CA() dot.gif{ trace("CA:     Destroy self.") ;}
InBlock.gif
InBlock.gif
private:
InBlock.gif    
long m_cRef;
ExpandedBlockEnd.gif}
 ;
None.gif
None.gifHRESULT __stdcall CA::QueryInterface(
const IID& iid, void** ppv)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{     
InBlock.gif    
if (iid == IID_IUnknown)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        trace(
"CA QI:  Return pointer to IUnknown.") ;
InBlock.gif        
*ppv = static_cast<IX*>(this) ;
ExpandedSubBlockEnd.gif    }
 
InBlock.gif    
else if (iid == IID_IX)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        trace(
"CA QI:  Return pointer to IX.") ;
InBlock.gif        
*ppv = static_cast<IX*>(this) ;
ExpandedSubBlockEnd.gif    }

InBlock.gif    
else if (iid == IID_IY)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        trace(
"CA QI:  Return pointer to IY.") ;
InBlock.gif        
*ppv = static_cast<IY*>(this) ;
ExpandedSubBlockEnd.gif    }

InBlock.gif    
else
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{         
InBlock.gif        trace(
"CA QI:  Interface not supported.") ;
InBlock.gif        
*ppv = NULL ;
InBlock.gif        
return E_NOINTERFACE;
ExpandedSubBlockEnd.gif    }

InBlock.gif    reinterpret_cast
<IUnknown*>(*ppv)->AddRef() ; 
InBlock.gif    
return S_OK ;
ExpandedBlockEnd.gif}

None.gif
None.gifULONG __stdcall CA::AddRef()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    cout 
<< "CA:     AddRef = " << m_cRef+1 << '.' << endl ;
InBlock.gif    
return InterlockedIncrement(&m_cRef) ;
ExpandedBlockEnd.gif}

None.gif
None.gifULONG __stdcall CA::Release() 
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    cout 
<< "CA:     Release = " << m_cRef-1 << '.' << endl ;
InBlock.gif
InBlock.gif    
if (InterlockedDecrement(&m_cRef) == 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        delete 
this ;
InBlock.gif        
return 0 ;
ExpandedSubBlockEnd.gif    }

InBlock.gif    
return m_cRef ;
ExpandedBlockEnd.gif}

None.gif
None.gif
//
None.gif
// Creation function
None.gif
//
None.gif
IUnknown* CreateInstance()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    IUnknown
* pI = static_cast<IX*>(new CA) ;
InBlock.gif    pI
->AddRef() ;
InBlock.gif    
return pI ;
ExpandedBlockEnd.gif}

None.gif
None.gif
//
None.gif
// IIDs
None.gif
//
None.gif
// {32bb8320-b41b-11cf-a6bb-0080c7b2d682}
None.gif
static const IID IID_IX = 
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif{0x32bb83200xb41b0x11cf,
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{0xa60xbb0x00x800xc70xb20xd60x82}}
 ;
None.gif
None.gif
// {32bb8321-b41b-11cf-a6bb-0080c7b2d682}
None.gif
static const IID IID_IY = 
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif{0x32bb83210xb41b0x11cf,
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{0xa60xbb0x00x800xc70xb20xd60x82}}
 ;
None.gif
None.gif
// {32bb8322-b41b-11cf-a6bb-0080c7b2d682}
None.gif
static const IID IID_IZ = 
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif{0x32bb83220xb41b0x11cf,
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{0xa60xbb0x00x800xc70xb20xd60x82}}
 ;
None.gif
None.gif
//
None.gif
// Client
None.gif
//
None.gif
int main()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    HRESULT hr ;
InBlock.gif
InBlock.gif    trace(
"Client: Get an IUnknown pointer.") ;
InBlock.gif    IUnknown
* pIUnknown = CreateInstance() ;
InBlock.gif
InBlock.gif
InBlock.gif    trace(
"Client: Get interface IX.") ;
InBlock.gif
InBlock.gif    IX
* pIX = NULL ; 
InBlock.gif    hr 
= pIUnknown->QueryInterface(IID_IX, (void**)&pIX) ;
InBlock.gif
InBlock.gif    
if (SUCCEEDED(hr))
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        trace(
"Client: Succeeded getting IX.") ;
InBlock.gif        pIX
->Fx() ;          // Use interface IX.
InBlock.gif
        pIX->Release() ;
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif
InBlock.gif    trace(
"Client: Get interface IY.") ;
InBlock.gif
InBlock.gif    IY
* pIY = NULL ;
InBlock.gif    hr 
= pIUnknown->QueryInterface(IID_IY, (void**)&pIY) ;
InBlock.gif    
if (SUCCEEDED(hr))
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        trace(
"Client: Succeeded getting IY.") ;
InBlock.gif        pIY
->Fy() ;          // Use interface IY.
InBlock.gif
        pIY->Release() ;
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif
InBlock.gif    trace(
"Client: Ask for an unsupported interface.") ;
InBlock.gif
InBlock.gif    IZ
* pIZ = NULL ;
InBlock.gif    hr 
= pIUnknown->QueryInterface(IID_IZ, (void**)&pIZ) ;
InBlock.gif    
if (SUCCEEDED(hr))
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        trace(
"Client: Succeeded in getting interface IZ.") ;
InBlock.gif        pIZ
->Fz() ;
InBlock.gif        pIZ
->Release() ;
ExpandedSubBlockEnd.gif    }

InBlock.gif    
else
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        trace(
"Client: Could not get interface IZ.") ;
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif
InBlock.gif    trace(
"Client: Release IUnknown interface.") ;
InBlock.gif    pIUnknown
->Release() ;
InBlock.gif    system(
"pause");
InBlock.gif    
return 0;
ExpandedBlockEnd.gif}

None.gif
None.gif
None.gif
None.gif