Polymeric component implementation issues

Category: VC/MFC -> ATL/ActiveX/COM Author: kevinwang65 Date: 2001-07-10 09:06:32
 
kevinwang65
2001-07-10 09:06:32
Recently watching "COM Principles and Applications " polymeric part of its implementation part is not very understanding , want to know the students give instructions , thank you
HRESULT  . CA :: NondelegationQueryInterface (const   IID &   iid,   void   ** ppv)
{
if   (  iid   ==   IID_IUnknown  )
{
* ppv   =   ( INondelegatingUnknown   *)   this  ;  
((IUnknown   *) (* ppv)) - > AddRef ()  ;         //   here actually call is AddRef or NondelegatingAddRef?
}   else   if   (  iid   ==   IID_SomeInterface  )  
{
* ppv   =   (ISomeInterface   *)   this  ;
((ISomeInterface   *) (* ppv)) - > AddRef ()  ;
}  
else
{
* ppv   =   NULL;
return   E_NOINTERFACE  ;
}
return   S_OK;
}
Description : CA is being aggregated classes. Suppose there is a class CB, is used
CA polymerization according to my understanding , CA and CB is CB reference count in the statistics , but I feel the upper part of the code (((IUnknown   *) (* ppv)) - > AddRef ()) call less than CB 's AddRef, I tried it , it actually calls is CA :: NondelegatingAddRef, do CA and CB are independent statistical reference count it? This is my understanding of the polymerization application counts are biased ?

CA inheritance structure is as follows :
class   INondelegatingUnknown
{
public:
virtual   HRESULT     __ stdcall     NondelegationQueryInterface (const   IID &   iid,   void   ** ppv)   =   0  ;
virtual   ULONG   __ stdcall     NondelegatingAddRef ()   =   0;  
virtual   ULONG   __ stdcall     NondelegationRelease ()   =   0;
};

class   CA  :   public   ISomeInterface,   public   INondelegatingUnknown
{
protected:
          ULONG                       m_Ref;

public:
          CA (IUnknown   * pUnknownOuter);
          ~ CA ();

public  :
//   Delegating   IUnknown
virtual   HRESULT     __ stdcall     QueryInterface (const   IID &   iid,   void   ** ppv)  ;
virtual   ULONG     __ stdcall     AddRef ()  ;  
virtual   ULONG     __ stdcall     Release ()  ;

//   Nondelegating   IUnknown
virtual   HRESULT       __ stdcall     NondelegationQueryInterface (const   IID &   iid,   void   ** ppv );
virtual   ULONG     __ stdcall     NondelegatingAddRef ();
virtual   ULONG     __ stdcall     NondelegationRelease ();

virtual   HRESULT   __ stdcall   SomeFunction ( )  ;

private  :
IUnknown     * m_pUnknownOuter;     //   pointer   to   outer   IUnknown
};
ISomeInterface inherits the IUnknown interface.
heyansheng
2001-07-10 09:19:24
on the inside, did not see the call m_pUnknownOuter- >   AddRef, would you give the code to see , they should be independent statistical reference counting .
fact, if you think about how when the heaviest piece to be released , they can return the reference count of zero, is an independent count or counts is unity , no problem
smartbook
2001-07-10 09:22:29

non- proxy IUnKnown code given above , there is a proxy as follows :
ULONG   CA :: AddRef   ()
{
if     (  m_pUnknownOuter   =!   NULL  )
return   m_pUnknownOuter- > AddRef ();
else
return   NondelegatingAddRef ();
}

ULONG   CA :: Release   ()
{
if     (  m_pUnknownOuter  ! =   NULL  )
return   m_pUnknownOuter- > Release   ();
else
return   NondelegationRelease ();
}

HRESULT   CA :: QueryInterface (const   IID &   iid,   void   ** ppv)
{
if     (  m_pUnknownOuter  ! =   NULL  )
return   m_pUnknownOuter- > QueryInterface (iid,   ppv);
else
return   NondelegationQueryInterface (iid,   ppv);
}

I feel that the key issue is : ((IUnknown   *) (* ppv)) - > AddRef (); this place will not be called non-proxy IUnKnown of AddRef interface , the results of my experiment was to adjust less , so it can not be cited in CA CB count put together statistics .
where there is a doubt that the following two conversion action :
* ppv   =   (INondelegatingUnknown   *)   this  ;     //   here , on this were offset , returns a point     INondelegatingUnknown   address
((IUnknown   *) (* ppv)) - > AddRef ()  ;   //   here , and no * ppv offset , return is still value * ppv , that point INondelegatingUnknown   address ( I feel should return to point IUnKnown address ) , even though I wrote void   * ppv1   =   (IUnkown   * ) (* ppv);   values ​​* ppv1 value and * ppv is still the same, why there is no offset it?
cremon
2001-07-10 09:32:17
you write your own or use the ATL template
schlumber
2001-07-10 09:46:56
casts and no pointer offset
just a description of the structure of the memory pointer
SingDrink
2001-07-10 09:57:30

this is an example of the book.
danyuning
2001-07-10 10:03:19

code also shows you this , if this component is polymerized , the two components of the reference count is unified counts
A918813
2001-07-10 10:17:05

may I say not very accurate, I mean * ppv   =   (INondelegatingUnknown   *)   this;   this operation was * ppv is this on the basis of the value of the offset after , but void   * ppv1   =   (IUnkown   *) (* ppv); did not do the offset on the basis * ppv , so not quite understand why.
cfy_anlen
2001-07-10 10:35:31

from the realization of the agent interface point of view, seems to be like this, but I feel that if requested CA 's IUnknown interface , will not be called to the proxy AddRef interface , because it will take
if   (  iid   ==   IID_IUnknown  )
{
* ppv   =   (INondelegatingUnknown   *)   this  ;    
((IUnknown   *) (* ppv)) - > AddRef ()  ;   //   here is the actual call AddRef or NondelegatingAddRef?
this process , but this process is the transfer agent interface AddRef less than the ( personal opinion ) .  
pmc33399
2001-07-10 10:46:54
does not look right
ppv and this value is not equal ?
xbbin
2001-07-10 10:53:15

Oh, I just wrote a small example :
class   A
{
public:
        virtual   void   funcA ()
        {
                cout   < <   " A   func "   < <   endl;
       }
};

class   B
{
public:
        virtual   void   funcB ()
        {
                cout   < <   " B   func "   < <   endl;
       }
};

class   Test:   public   A,   public   B    
{
public:
Test ();
virtual   ~ Test ();
        void   Print ()
        {
                void   * ptr   =   (B   *) this;
                cout   < <   hex   < <   ptr   < <   endl;
                cout   < <   hex   < <   this   < <   endl;
       }
};
result of this output , ptr , and this is unequal , that and the structure of the CA should be similar , right ?
q742047774
2001-07-10 10:58:26
I tested true
and change it if the order of succession
class   Test:   public   B,   public   A
this
these two values ​​is consistent with the
opinion between the subclass and superclass casts do not change when describing
and will adjust the pointer position based on inheritance thus matching
qywj1972
2001-07-10 11:06:03
top, do not sink , hoho