在第一次看关于聚合实现的时候年利觉得有点晕,又仔细琢磨了下,现在基本上搞明白了里面的曲曲折折,现记录一下当时不太理解的地方
(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这个申请到的对象,也可能是我没看明白吧,这块书附带的源代码里也没这些的代码我就不再贴了..
原文链接:https://www.f2er.com/javaschema/287842.html