interface IUnknown {
  // runtime type discovery
  HRESULT QueryInterface([in] REFIID riid,
                         [out, iid_is(riid)] void **ppv);
  // lifetime management
  ULONG AddRef();
  ULONG Release();
}
 
COM allows every object to implement these
methods as it chooses (within certain restrictions, as described in
Chapter 5, "COM
Servers"). The canonical implementation is as follows:
// Server lifetime management
extern void ServerLock();
extern void ServerUnlock();
class CPenguin : public IBird, public ISnappyDresser {
public:
  CPenguin() : m_cRef(0) { ServerLock(); }
  virtual ~CPenguin()    { ServerUnlock(); }
  // IUnknown methods
  STDMETHODIMP QueryInterface(REFIID riid, void **ppv) {
      if( riid == IID_IBird || riid == IID_IUnknown )
          *ppv = static_cast<IBird*>(this);
      else if( riid == IID_ISnappyDresser )
          *ppv = static_cast<ISnappyDresser*>(this);
      else *ppv = 0;
      if( *ppv ) {
          reinterpret_cast<IUnknown*>(*ppv)->AddRef();
          return S_OK;
      }
      return E_NOINTERFACE;
  }
  ULONG AddRef()
  { return InterlockedIncrement(&m_cRef); }
  ULONG Release() {
      ULONG l = InterlockedDecrement(&m_cRef);
      if( l == 0 ) delete this;
      return l;
  }
  // IBird and ISnappyDresser methods...
private:
    ULONG m_cRef;
};
 
These common assumptions are not the only
possibilities. Common variations include the following: