# Component Objects: C++ Nested Classes

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;