Essential COM

C++ , (overhead) vptr ( , sizeof (void*) == 4). , , , , , . , , , vptr , , , . . , , , vptr .

, , QueryInterface IUnknown . . QueryInterface , IUnknown. , vptr , , - . (transient) " " Microsoft (Microsoft white paper The Programmer's Cookbook), (Crispin Goswell) (http://www.microsoft.com/oledev). " " (tearoff).

. , , . , QueryInterface QueryInterface . , : 1) , , 2) , , , , . IBoat :

 class CarBoat : public ICar {     LONG m_cRef;     CarBoat (void): m_cRef(0) {}    public:       // IUnknown methods        //   IUnknown      STDMETHODIMP QueryInterface(REFIID, void**);     STDMETHODIMP_(ULONG) AddRef(void);     STDMETHODIMP_(ULONG) Release(void);       // IVehicle methods        //   IVehicle      STDMETHODIMP GetMaxSpeed(long *pMax);       // ICar methods        //   ICar      STDMETHODIMP Brake(void);       // define nested class that implements IBoat       //      ,   IBoat     struct XBoat : public IBoat {         LONG m_cBoatRef;           // back pointer to main object is explicit member            //           -              CarBoat *m_pThis;         inline CarBoat* This() { return m_pThis; }         XBoat(CarBoat *pThis);         ~XBoat(void);         STDMETHODIMP QueryInterface(REFIID, void**);         STDMETHODIMP_(ULONG) AddRef(void);         STDMETHODIMP_(ULONG) Release(void);         STDMETHODIMP GetMaxSpeed(long *pval);         STDMETHODIMP Sink(void);     };       // note: no data member of type Xboat       //  :         Xboat }; 

QueryInterface , IBoat:

 STDMETHODIMP CarBoat::QueryInterface(REFIID riid, void **ppv)  {      if (riid == IID_IBoat)          *ppv = static_cast<IBoat*>(new XBoat(this));     else if (riid == IID_IUnknown)         *ppv = static_cast<IUnknown*>(this);     :    :    : 

IBoat . QueryInterface AddRef :

 ((IUnknown*)*ppv)->AddRef(); 

AddRef QueryInterface . , , . . :

 CarBoat::XBoat::XBoat(CarBoat *pThis) : m_cBoatRef(0), m_pThis(pThis)  {     m_pThis->AddRef(); } CarBoat::XBoat::~XBoat(void)  {     m_pThis->Release(); } 

, QueryInterface , . ( ), , , AddRef, :

 STDMETHODIMP CarBoat::XBoat::QueryInterface(REFIID riid, void**ppv)  {     if (riid != IID_IBoat)          return This()->QueryInterface(riid, ppv);     *ppv = static_cast<IBoat*>(this);     reinterpret_cast<IUnknown*>(*ppv)->AddRef();     return S_OK; } 

, , , , . , , :

 STDMETHODIMP_(ULONG) CarBoat::XBoat::AddRef (void)  {     return InterlockedIncrement(&m_cRef); }  STDMETHODIMP_(ULONG) CarBoat::X8oat::Release(void) {     ULONG res = InterlockedDecrement(&m_cBoatRef);     if (res == 0)          delete this;       // dtor releases main object       //            return res; } 

, This() , . , , , .

, . , . , 4 . . - , 4 vptr. 1. - , (custom memory allocator), 4 / , - malloc/operator new. , 4 , . , 12 , , 16 , , , new. , , . , .

, . , QueryInterface , , , . , 24 32 , vptr , QueryInterface. , . , QueryInterface , , . - , , ( QueryInterface) . , .

, : " ?" ; . , , , ITruck ( ), IMonster ruck ( - ), IMotorcycle ( ), IBicycle ( ), IUnicycle ( ), ISkateboard ( ) IHelicopter ( ), IVehicle. , , , . :

 class GenericVehicle : public IUnknown {     LONG m_cRef;     IVehicle *m_pTearOff;       // cached ptr to tearoff       //                GenericVehicle(void) : m_cRef(0), m_pTearOff(0) {}        // IUnknown methods        //   IUnknown      STDMETHODIMP QueryInterface(REFIID, void **);     STDMETHODIMP_(ULONG) AddRef(void);     STDMETHODIMP_(ULONG) Release (void);       // define tearoff classes       //            class XTruck : public ITruck { ... };     class XMonsterTruck : public IMonsterTruck { ... };     class XBicycle : public IBicycle { ... };     :    :    : }; 

, , . QueryInterf , :

 STDMETHODIMP GenericVehicle::QueryInterface(REFIID riid ,void **ppv) {     if (riid == IID_IUnknown)         *ppv = static_cast<IUnknown*>(this);     else if (riid == IID_ITruck) {         if (m_pTearOff == 0)           // no tearoff yet, make one           //        ,              m_pTearOff = new XTruck(this);           if (m_pTearOff)             // tearoff exists, let tearoff QI             //      ,     QI               return m_pTearOff->QueryInterface(riid, ppv);           else             // memory allocation failure              //                      return (*ppv = 0), E_NOINTERFACE;     } else if (riid == IID_IMonsterTruck) {         if (in_pTearOff == 0)           // no tearoff yet, make one           //        ,                m_pTearOff = new XMonsterTruck(this);             if (m_pTearOff)               // tearoff exists, let tearoff QI                //      ,     QI               return m_pTearOff->QueryInterface(riid, ppv);       else         // memory allocation failure          //              return (*ppv = 0), E_NOINTERFACE;     } else ...     :    :    : } 

QueryInterface . , 12 (vptr IUnknown + + ). , 24 28 ( 12 + Vehicle vptr + + + ( ) malloc (memory allocation - )).

, :

 class GenericVehicle : public ITruck,                        public IHelicopter,                         public IBoat,                        public ICar,                         public IMonsterTruck,                         public IBicycle,                         public IMotorcycle,                         public ICar,                        public IPlane,                        public ISkateboard {     LONG m_cRef;     // IUnknown methods -   IUnknown     :    :    : }; 

, 44 ( vptr + ). , , , . , ( - ). , . , , . , , , .


1 , AddRef. , , ( ) AddRef/Release.



Suschnost' tehnologii SOM
Essential COM
ISBN: 0201634465
EAN: 2147483647
Year: N/A
Pages: 103
Authors: Don Box

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net