头大的智能指针

虽然学程序都3年了,可是本人的基本功有的时候自己都怀疑。以前只听说过智能指针但一直没有用过。该来的总该回来躲是躲不掉的。到底让我碰上了。

这两天一直在学读写xml。为了简单当然得站在巨人的肩膀上了,所以我用的是很普遍的MS XML读取。废一句话刚开始写了一点程序还没成型所以现在还不想写出来丢人。今天只写一下智能指针的问题。

MSXML2::IXMLDOMDocument     docPtr;

就是这个家伙使用完了退出程序总是报错。所以按照以前的方法:

 if (docPtr != NULL)
 {
  docPtr->Release();
  docPtr = NULL;
 }

居然不行!!着实郁闷!!老经验:“你遇到的问题别人都遇到过,上网搜!”。终于黄天不负我程序有心人啊,问题终于找到并解决了。所以赶紧在这里记下一笔。

智能指针不用我们Release(),在赋值时也不用我们先判断原指针是否有效,然后Release(),然后再AddRef()等等一连串麻烦的调用....局部智能指针在函数结束时,会自动调用虚构函数以调用Release()。

  当在一个类中中把智能指针作为类的数据成员。然后在一个类成员函数中调用::CoInitialize()初始化COM库,并初始化作为类的数据成员的智能指针。这就涉及另一个函数:::CoUninitialize()了。这个函数在什么时机调用比较好?当然是所有智能指针都释放了后再调用。但作为一个类的数据成员,如果这个数据成员本身也是一个类时,比如智能指针,会在这个类的虚构函数调用结束后再调用数据成员的虚构函数。这个问题又回到了刚才在一个函数使用智能指针的问题,也即一个范围的问题。

  所以不能让智能指针的虚构函数来释放接口指针。要在类的虚构函数中调用::CoUninitialize()之前手动释放接口指针。如何释放?
 
if (docPtr != NULL)
 {
  docPtr->Release();
 }
 
      这样释放是有问题的。因为Release()只是使COM对象计数器减一,但智能指针的数据成员接口指针m_pInterface并没有为NULL,所以在智能指针的虚构函数中还会调用Release(),所以还会有Access Vali...的错误提示。
  那这样呢:
  
if (docPtr != NULL)
 {
  docPtr->Release();
  docPtr = NULL;
 }
 
      这样先释放接口指针,再使其为NULL这样在调用智能指针的虚构函数时,因智能指针的数据成员m_pInterface为NULL,所以不会调用Release()了。
  但由于智能指针重载了=操作符,当docPtr = NULL时,会先调用AddRef,再调用m_pInterface的一份附值(临时值)的Release(),此时m_pInterface等于NULL。这样就调用了两次Release()。
 
所以正确的做法是(至少这么做不出错):
if (docPtr != NULL)
 {
  docPtr = NULL;
 }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值