注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

天地不仁,以万物为Googol!

天行有常,不以物喜,不以己悲……

 
 
 

日志

 
 

终于理解为什么auto_ptr是销毁式拷贝的语义了!  

2005-12-20 21:50:23|  分类: 默认分类 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
假设你需要给一个类A传入另一个类的实例b,且A会在很长一段时间内持有b。如果b又需要多态,因此A只能维护一个指向b的指针的话,如果这样写:
 
class A
{
public:
    setb(B *arg){ pb=arg; }
}
 
那么必然会出现:类A何时释放b的问题。比如:
 
A a;
{ B b;
a.setb(&b);}//出了这里,a.pb不再有效,但没有提示
 
或者
 
A a;
B *b = new B;
a.setb(b);
delete b;//这里以后,a.pb也不再有效,但没有提示
 
以上错误,都会在超出有效区后,第一次使用A.pb时爆发。这就是常见的,但难以定位的指针悬挂(野指针)错误。
 
如果使用auto_ptr做参数:
 
class A
{
public:
    setb(auto_ptr<B> arg){ pb=arg; }
}
 
那么,在传递参数时,会将arg所指向的东西传递给pb,并且摧毁arg,使其无效。这样,对于以上错误:
 
A a;
{ B b;
a.setb(auto_ptr<B>(&b));//销毁&b时,会报错,因为栈空间是系统维护的,不能动态delete
 
或者
 
A a;
B *b = new B;
a.setb(auto_ptr<B>(b));
delete b;//报错,重复删除同样的地址引用
 
这样,虽然不能完全禁止这类错误,但至少报错的地点与犯错误的位置更近了。而且,由于void*不能隐性转换为auto_ptr(这点设计得真强!),也提示使用者,这里的指针与别的地方的指针语义不同(由持有类维护,不需要手动删除),需要小心处理。
 
果然是,了解语义重于了解语法,auto_ptr应该在合理的地方推广使用。
 
ps 一只蟑螂在我写blog的时候,在我面前爬来爬去,不知道他是否能看懂………………
 
后记:经过试验,此种方法在debug时汇报错,但在release中不会,看来debug版的auto_ptr有完善的保护机制。
  评论这张
 
阅读(151)| 评论(4)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017