The next example shows how the same object is declared and initialized using the C++ nested class approach. As in the C example, the nested class declaration includes one data structure for each interface and four private data members: an object-level reference count, two interface pointers, and a pointer to the enclosing object. The private implementations of the IUnknown methods are called by the implementations declared for the derived interfaces. For each interface implementation, there is a structure containing a public constructor and destructor, private declarations of the interface methods, a private pointer to CObj, and an interface-level reference counter for debugging purposes. To allow the nested interface classes to access the private members of the outer class, each interface class is made a friend of the outer class.
The benefits of implementing with C++ nested classes lie in the ability to include initialization code and method implementation inline. However, inline declaration is for the convenience of illustration and is not required.
class CObj { private: ULONG m_ObjRefCount; LPSTORAGE m_pStg; LPOLEOBJECT m_pOleObj; CDOC * m_pCDoc; public: CObj(); ~CObj(); struct CUnknown : IUnknown { private: ULONG m_RefCount; CObj * m_pCObj; public: CUnknown(CObj (pCObj) { m_pCObj = pCObj; m_RefCount = 0; } HRESULT QueryInterface(REFIID riid, LPVOID * ppvObj) ULONG AddRef(void) { return ++m_ObjRefCount; } ULONG Release(void); } friend CUnknown; CUnknown m_Unknown; struct InterfaceA : InterfaceA { private: ULONG m_RefCount; CObj * m_pCObj; public: CInterfaceA(CObj *pCObj) { m_pCObj = pCObj; m_RefCount = 0; } HRESULT QueryInterface(REFIID riid, LPVOID * ppvObj) ULONG AddRef(void) { return ++m_ObjRefCount; } ULONG Release(void); HRESULT MethodA1(LPVOID * ppvObj); HRESULT MethodA2(DWORD dwArg); } friend CInterfaceA; CInterfaceA m_InterfaceA; struct InterfaceB : InterfaceB { private: ULONG m_RefCount; CObj * m_pCObj; public: CInterfaceB(CObj *pCObj) { m_pCObj = pCObj; m_RefCount = 0; } HRESULT QueryInterface(REFIID riid, LPVOID * ppvObj) ULONG AddRef(void) { return ++m_ObjRefCount; } ULONG Release(void); HRESULT MethodB1(void); HRESULT MethodB2(DWORD dwArg1, DWORD dwArg2); } friend CInterfaceB; CInterfaceB m_InterfaceB;