学习<Com原理与应用>遇到的问题(关于聚合) addref去掉就出错,addref和release 是一对用这样可以保证内存中只有一个程序进程当计数器为0时,可以自动释放, 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 我试着按照我的意思改了程序,和原来程序的运行效果一样。bobqi(灰冷) ,我这样改,AddRef和Release应该仍然成对。但是我有点怕是不是我有没考虑到的地方,这样改是不是在别的情况下会出错。 你已经知道“先AddRef是为了防止Init中出现错误时导致外部对象自动销毁”,所以在Init代码中没有错误时效果是一样的。代码的健壮性是非常重要的,所以才有“异常”技术的出现。 有些语言,例如Object Pascal,它的变量是自动释放的,不能如C++般灵活控制。这时候,灵活的C只好迁就Pascal,所以一个借口指针在一个变量的作用域里,AddRef与Release都是一对一对的。 Buma(灌水)兄:先AddRef是为了避免Init函数中调用Release函数后,存在m_Ref为0而释放外部对象的可能。我是把Init函数里的Release移到CreateInstance里,这样可以省却一对AddRef,Release。musicdancer(饭盆)兄,我这样是不是并没有破坏这个保险措施?俺还有另一个问题: p107-p108关于CB的析构函数的讨论的疑点: 析构函数里面为何要使用 m_Ref=1; IUnknown *pUnknownOuter = this; pUnknownOuter->AddRef(); 直接对m_Ref进行赋值2不就行了么? 你要知道,这个程序是你自己编的,你控制了一切,那你当然觉可以做到简洁一些.然而,不幸的是,我们不能假设其他人在使用你的组件的时候和你一样的想法,我们必须坚持一定的原则和作最坏的假设.所以别人不知道你究竟怎样处理那对计数,就假设你符合com一般的原则. 你上面说的那个m_Ref=1; IUnknown *pUnknownOuter = this;pUnknownOuter->AddRef(); //这里面加的是m_Ref? 谢谢musicdancer(饭盆)兄:您说的对,我刚开始学,一些概念还不是很清楚,我想 我只要提供接口给外面,只要一个组件内部能按照com规范完成功能,至于组件内部实现细节用户不必了解。像这个例子中涉及的init和createinstance函数都是组件内部的事。那个IUnknown *pUnknownOuter = this;pUnknownOuter->AddRef();我以为是调用了外部对象的AddRef,对m_Ref加一,不知道对不对? 关于m_ref.就这3句来说,你是对的.因为没看到源程序是怎样,我也不太明白这里的意思. 按你的方法:把Init函数最后的pUnknownOuter->Release();语句和CreateInstance函数中的 pObj->AddRef();语句去掉在这个程序里没有问题,只要你知道init中干了什么.引用计数com没有作更多的要求,唯一要求是给记清楚了,不让内存泄漏.:)我前面在楼上说的好像不太对题,:(. 书上写的是对的,我想其实老潘也没讲清楚,在生成之后立即addref是为了防止访问竞争,即有外部对象的接口调用了pUnkown->release(),导致外部对象的引用计数为0,个人理解不知道对不对? to chenyf(卖女孩的小火柴) 我刚才就在想什么情况下,刚生成对象,外部对象的接口就调用了pUnkown->release(). 由于没看源代码,搞不清楚这里pUnknownOuter和pObj的关系.个人觉得这本书在有些方面(比如关于包容聚合等)轻描淡写了些(老潘太厉害了).看看 <<inside com>>比较爽朗些.如果你再遇到问题(比如,在聚合里很多初学者会遇到一个想不通的死循环),可以先查找一下. 死循环也是因为老潘的聚合方法过于昏涩,用一个强制转换替换vtable,com本质论的例子就很简明,C++学的不好也马马虎虎看得懂 chenyf(卖女孩的小火柴),你的理解是对的,确实是为了防止访问竞争。BTW,你是人贩子?:)musicdancer(饭盆):我有inside com的电子版,觉得比pam的通俗易懂点。同学还有本《本质论》,听说恨难,真是学无止境啊:(。聚合是我碰到的第一个难点,啃了好久才明白。你们有没有用com实际做过项目啊?感觉咋样? 还想问一下,我咋从来没收到过csdn的邮件啊,是不是没有邮件服务? 没用com做过项目,不过我喜欢com.csdn早就不发邮件了,可能负担太重. 很高兴看到大家的讨论,有几个疑点解释一下,希望能够对你们有所帮助。1 析构函数的处理不是为了防止访问竞争,而是为了AddRef和Release调用配对。书上有解释。但是很多人不明白,我也不希望在这种太细节的地方让大家钻牛角。但这确实是有必要的。2 聚合的实现方法有多种,MFC和ATL的实现与这本书不同,不过这些实现的原理都是一致的。内部对象实现两个IUnknown是COM规范的要求,也是COM对象IUnknown接口一致性的要求。具体实现细节在不同的实现方法中表现形式不见得相同,但是本质是一致的。相比较而言,用内嵌类实现COM接口的方法(也就是MFC采用的方法)要直观一些,而用多继承的方法涉及到过多C++知识,显得晦涩一些。 没想到能把潘爱民老师引来。谢谢您的指教。再问一下:1、不知道我在上面关于AddRef和Release的想法对不对?2、《本质论》是不是真的很难,需要一些com基础才行? 答复daydream,1 AddRef和Release是必需的,为了避免引用计数回到0的情况。在初始化(即Init函数)的时候,有可能要把自己的接口指针交给别的程序,所以加一层保护是必要的。引用计数是共享资源的有效实现技术,而这种保护技术又是一种通常的技术,并不局限于COM的聚合模型。2 “Essential COM”并不难,但要真正理解书上的内容确实需要扎实的基础。 问CToolTipCtr怎么用的? 请问如何获知进程切换? 请教各位大哥:怎样编程设置系统环境变量?????? 如何将实现将本地的文件上传到服务器?怎样实现?谢谢 小师妹快要急死了!在线等待---关于InstallShield的打包问题,一定给分! 高手这么多,我就不信不能解决这个问题!!!!!!!!! 读写文件得一个问题!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 怎样生成48-48之间的随机数?请指教!! 如何屏蔽对标题栏的双击 ADO或SQL操作ACCESS数据库问题急急急 大3 学什么好泥?? 关于 com的使用
bobqi(灰冷) ,我这样改,AddRef和Release应该仍然成对。
但是我有点怕是不是我有没考虑到的地方,这样改是不是在别的情况下会出错。
外部对象的可能。我是把Init函数里的Release移到CreateInstance里,这样可以
省却一对AddRef,Release。musicdancer(饭盆)兄,我这样是不是并没有破坏这个保险措施?俺还有另一个问题:
p107-p108关于CB的析构函数的讨论的疑点:
析构函数里面为何要使用 m_Ref=1;
IUnknown *pUnknownOuter = this;
pUnknownOuter->AddRef();
直接对m_Ref进行赋值2不就行了么?
m_Ref=1;
IUnknown *pUnknownOuter = this;
pUnknownOuter->AddRef(); //这里面加的是m_Ref?
提供接口给外面,只要一个组件内部能按照com规范完成功能,至于组件内部实现细节用户
不必了解。像这个例子中涉及的init和createinstance函数都是组件内部的事。那个IUnknown *pUnknownOuter = this;
pUnknownOuter->AddRef();
我以为是调用了外部对象的AddRef,对m_Ref加一,不知道对不对?
就这3句来说,你是对的.
因为没看到源程序是怎样,我也不太明白这里的意思.
把Init函数最后的pUnknownOuter->Release();语句和CreateInstance
函数中的 pObj->AddRef();语句去掉
在这个程序里没有问题,只要你知道init中干了什么.
引用计数com没有作更多的要求,唯一要求是给记清楚了,不让内存泄漏.:)我前面在楼上说的好像不太对题,:(.
在生成之后立即addref
是为了防止访问竞争,
即有外部对象的接口调用了pUnkown->release(),
导致外部对象的引用计数为0,
个人理解不知道对不对?
我刚才就在想什么情况下,刚生成对象,外部对象的接口就调用了pUnkown->release().
由于没看源代码,搞不清楚这里pUnknownOuter和pObj的关系.
个人觉得这本书在有些方面(比如关于包容聚合等)轻描淡写了些(老潘太厉害了).
看看 <<inside com>>比较爽朗些.
如果你再遇到问题(比如,在聚合里很多初学者会遇到一个想不通的死循环),可以先查找一下.
用一个强制转换替换vtable,
com本质论的例子就很简明,
C++学的不好也马马虎虎看得懂
musicdancer(饭盆):
我有inside com的电子版,觉得比pam的通俗易懂点。同学还有本《本质论》,听说恨难,
真是学无止境啊:(。聚合是我碰到的第一个难点,啃了好久才明白。你们有没有用com实际做过项目啊?感觉咋样?
1、不知道我在上面关于AddRef和Release的想法对不对?
2、《本质论》是不是真的很难,需要一些com基础才行?
1 AddRef和Release是必需的,为了避免引用计数回到0的情况。在初始化(即Init函数)的时候,有可能要把自己的接口指针交给别的程序,所以加一层保护是必要的。引用计数是共享资源的有效实现技术,而这种保护技术又是一种通常的技术,并不局限于COM的聚合模型。2 “Essential COM”并不难,但要真正理解书上的内容确实需要扎实的基础。