描述:
我都糊涂了,
CComContainedObject implements IUnknown by delegating to the owner object's IUnknown. (The owner is either the outer object of an aggregation, or the object for which a tear-off interface is being created.) 这是什么意思呀?
CComContainedObject不是指向被聚集的对象吗?它和代理IUnknown和非代理IUnknown什么关系呀?
麻烦老大们给解释一下,别告诉我那些链接,我看了好多链接了,没看懂:(
解决方案1:
前面的 zhangcrony(前后都是路,橫豎都是一) 已经把那句话翻译了,所谓的“delegating”指CComContainedObject自己不实现IUnknown的具体细节,而通过简单的调用所有者的IUnknown实现来实现IUnknown。下面就ATL实现可聚合组件的方式来说明CComContainedObject的用处。
假设楼主自己编写的类CC实现了接口IA,但是类CC并没有实现IUnknown的三个函数(如果使用向导生成的,最基本地只派生自CComObjectRootEx和CComCoClass),它们一般是由CComObject实现的。
当外部对象的IUnknown*通过CoCreateInstance传给组件时,由于CC支持被聚合,因此类厂通过CComAggObject< CC >的形式创建了一个类CComAggObject的实例(注意,CC的实例并没有被创建,而CComAggObject是一个和CComObject一样的实现了IUnknown的那三个函数的类),此实例具有自己的引用记数且只实现IUnknown。
而CC的实例是通过CComAggObject的一个成员变量生成的(由于CC的实例是CComAggObject的成员变量而在CComAggObject实例生成时自动由CComAggObject的构造函数完成生成),此成员变量的类型是CComContainedObject,它是CC的派生类(通过如此的形式:template< class U > class CComCotainedObject : public U;),它和CComObject及CComAggObject一样,都是只实现了IUnknown的三个函数,其他什么都没做。
当CComAggObject构造时,外部对象的指针pUnkOuter通过其构造函数的参数传给CComAggObject的实例,而CComAggObject仅仅简单的将它再传递给CComContainedObject实例,而CComAggObject自己依然保持着其引用记数(因为 union { long m_dwRef; IUnknown* m_pOuterUnknown; };)。
因此通过外部对象暴露给客户的IA接口实际是指向CComContainedObject的实例,由于是被聚合的,所以对IA的AddRef等调用必须委派给pUnkOuter,所以CComContainedObject的IUnknown的三个实现都是将调用委派给外部对象,因为它是IA接口的实现者。
对于tear-off也有类似的情况,所以其也被应用在CComCachedTearOffObject中