COM原理与应用中关于聚合实现的纪要

  在第一次看关于聚合实现的时候年利觉得有点晕,又仔细琢磨了下,现在基本上搞明白了里面的曲曲折折,现记录一下当时不太理解的地方

(1)

2

  我这这样理解的:问题1与问题2其实是相互关联的,对于问题2,为什么聚合时一定要传IID_IUnknown,这个是因为外部对象要想能查询到对象A包含的接口就必须拿到对象A的INondelegatingUnknown接口,为什么不是IUnknown接口呢?因为对象A在被聚合时IUnknown只是做为一个代理将引用计数中转到了外面对象那,而真正的自身的IUnknown的功能由INondelegatingUnknown接口来取代,有了这个接口外部对象才能查询到对象A的内部接口,以及控制外部对象的生存周期.,好了问题2如果想明白了问题1也就清楚了,因为被聚合时外部要得到INondelegatingUnknown接口,所以会有

 *ppv = (INondelegatingUnknown *) this ;

这样的操作了,不过这里还有一点可能不好明白的,这里是把一个INondelegatingUnknown指针传出去了,而在外面保存这个接口指针的是一个IUnknown类型的接口,那么如果外面的IUnknown调用AddRef()函数会调用到哪个函数呢?实际调用到的是INondelegatingUnknown接口的NondelegatingAddRef()函数,这个只所以是这样,是因为这些虚函数的调用是通过虚表实现的,而

 *ppv = (INondelegatingUnknown *) this ;

在执行这个时会把this指针做偏移,使*ppv 指向的接口的虚表指向INondelegatingUnknown的虚表地址

  我觉得我的理解应该是正确的,如果有不对的还请指正.

  另外,对于书上第P98-P99页的CBFactory::CreateInstance函数的实现感觉有点问题,在New CB()后,执行QueryInterface()之前没有调用Addref(),这样当QueryInterface()失败时就会有内存泄漏的发生,因没有一个机会去delete这个申请到的对象,也可能是我没看明白吧,这块书附带的源代码里也没这些的代码我就不再贴了..

相关文章

什么是设计模式一套被反复使用、多数人知晓的、经过分类编目...
单一职责原则定义(Single Responsibility Principle,SRP)...
动态代理和CGLib代理分不清吗,看看这篇文章,写的非常好,强...
适配器模式将一个类的接口转换成客户期望的另一个接口,使得...
策略模式定义了一系列算法族,并封装在类中,它们之间可以互...
设计模式讲的是如何编写可扩展、可维护、可读的高质量代码,...