CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
山寨机中的战斗机! 程序优化工程师到底对IT界有没有贡献
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C/C++ >  C语言

to 令狐虫:有关你的auto_ptr的问题

楼主cber(cber)2002-08-06 16:07:24 在 C/C++ / C语言 提问

不知道怎么回事,给你回的mail总是被退回来了,不得已只能在这说了:(  
   
  你的问题:  
          这几天在工作之余,下载了SGI   STL来看。首先开刀的是auto_ptr(我觉得这个跟STL的其它部分联系不大,容易读懂,呵呵),但是还是碰到了一些疑问。但是CSDN最近似乎忙得很,登录都很困难,失望之余想到了您,希望您能帮助我。  
   
          我的问题是这样子的,我按自己的理解写了也一个smart_point类,其中大部分是是参照STL   auto_ptr写的,但是有几个地方我觉得难以理解,所以按自己的想法做了些改动,我想知道,STL为什么那样做,我的类又有哪些缺陷呢?  
   
          1、auto_ptr::release()问题。这个函数我觉得很难理解,从代码上看,这个函数的作用是返回自身所指的内存的地址,然后【将自身指针指向空】,为什么要这样做呢?比如auto_ptr在其copy   constructor里,就对内部的指针_point赋予了这样的值:__a.release()。这样一来,__a不是不能用了吗?我在我的版本里改用了get函数,这样会造成什么问题吗?还有,我的赋值运算符重载代码也是自己写过的,我的理解是:一旦一个指针p被赋了新值,那么它原来的值就会悬空从而造成泄露,所以我在每次赋值操作的时候将其旧值删除。但是这样会造成一个问题,就是两个指针指向同一块内存区的问题,隐约觉得这样的问题要用引用计数解决,可是不知道怎么写,因为这个操作似乎是对赋值运算符的右值操作(当它被赋给别人时,它的引用计数+1),重载运算符似乎也不能解决这个问题啊。至于STL的代码,我则又不理解了,它为什么用a.release()呢?这样右值的指针不是也失效了?  
   
          2、在STL里还定义了一个auto_ptr_ref结构,这个结构起到了什么用处?  
   
          3、还有一个问题我觉得奇怪。本来我想在main函数中写这样的代码的:smart_point<int>   ptr1   =   new   int(6);   可是编译器(Borland   C++   Builder   6/Command   Line)给出了一个“   Cannot   convert   'int   *'   to   'smart_point<int>'”的错误,我觉得奇怪,按我的理解,这样的写法,应该会调用ptr1(int   *)构造函数,从而将内部指针_point指向申请出来的内存,可是为什么会错呢?   smart_point<int>   ptr1(new   int(6));这样的写法就不错。难道是我的想法错了?  
   
  源码附后,希望cber先生能在百忙中给个回复。多谢。  
   
                                                                                                                                          令狐虫  
                                                                                                                                      2002/08/06  
  ----------------------------------  
  template   <class   T>  
  class   smart_point  
  {  
  public:  
  //Interface  
  explicit   smart_point(T   *p   =   NULL)   :   _point(p)   {};  
   
  smart_point(smart_point   &p)   :   _point(p.get())   {};   //注:STL的auto_ptr这里写的是p.release(),但现在还不理解这个release究竟干什么用。  
   
  ~smart_point()   {   if   (_point)   delete   _point;   };  
   
  T&   operator*()   const  
  {   return   *_point;   };  
   
  T*   operator->()   const  
  {   return   _point;   };  
   
  smart_point&   operator=(smart_point   &p)       //注:实现方法与STL有所不同,感觉STL的写法很难理解  
  {    
  if   (p.get()   !=   this->_point)  
  if   (this->_point   !=   NULL)  
  delete   this->_point;  
  this->_point   =   p.get();  
  return   *this;  
  };  
   
  smart_point&   operator=(T   *p)  
  {  
  if   (p   !=   this->_point)  
  if   (this->_point   !=   NULL)  
  delete   this->_point;  
  this->_point   =   p;  
  return   *this;  
  };  
   
  T*   get()  
  {   return   _point;   };  
  private:  
  T   *_point;  
  };  
   
  //------------------Main   for   Test--------------------  
  int   main()  
  {  
  //   int   *p1   =   new   int(5);  
  //   int   *p2   =   new   int(6);  
  //   smart_point<int>   ptr1(p1);  
  //   smart_point<int>   ptr2(p2);  
   
  //   smart_point<int>   ptr1   =   new   int(5);             //这个为什么会错?  
  //   smart_point<int>   ptr2   =   new   int(6);  
   
  smart_point<int>   ptr1(new   int(3));  
  smart_point<int>   ptr2(new   int(4));  
  smart_point<int>   ptr3(ptr2);  
   
  cout   <<   "*ptr1   =   "   <<   *ptr1   <<   endl;  
  cout   <<   "*ptr2   =   "   <<     *ptr2   <<   endl;  
  cout   <<   "*ptr3   =   "   <<     *ptr3   <<   endl;  
   
  ptr2   =   ptr1;  
  cout   <<   "*ptr1   =   "   <<   *ptr1   <<   endl;  
  cout   <<   "*ptr2   =   "   <<     *ptr2   <<   endl;  
   
  return   0;  
  }  
   
  =========================================================================  
  我的回答:  
  其实对于ISO   14882(也就是大家所知道的C++标准文档)中的auto_ptr,很多人(包括国外的一些牛人)都觉得它的做法不是很好,目前在boost中对于smart   pointer有几个不错的实现,你可以去参考一下它们的做法(boost源码可以从网上下载http://www.boost.org)  
   
  release()在copy   ctor中的作用就是:保证一份memory只能有一个owner,如果你用get(),那么你的程序在对这两个owner做destroy动作时   ,会在第二次调用dtor时得到一个undefined的行为。引用计数的方式可以参见boost.share_ptr  
   
  auto_ptr_ref的问题,我现在记得不是很清楚了,需要翻翻书才行:(  
   
  smart_point<int>   ptr1   =   new   int(6);编译出错的原因在这:  
  explicit   smart_point(T   *p   =   NULL)   :   _point(p)   {};  
  因为你的ctor是explicit的,所以不能自动为你实现implicit   conversion  
   
  因为最近对于C++的书籍几乎没有接触,所以第二个问题可能还是需要你自己去查书了,忘见谅 问题点数:1、回复次数:4Top

1 楼cber(cber)回复于 2002-08-08 15:37:17 得分 0

还没有来啊:(  
   
  拜托下次用一个可以收到回复的mail地址,这样我就不会搞得这么复杂了  
   
  算了,自己up一下,等你看完后结贴Top

2 楼anrxhzh(百宝箱)回复于 2002-08-08 17:58:44 得分 1

http://www.josuttis.com/libbook/auto_ptr.html  
   
  auto_ptr   and   auto_ptr_ref    
  This   page   contains   details   about   the   motivation   of   auto_ptr_ref   as   part   of   the   auto_ptr   class.  
   
  Top

3 楼anrxhzh(百宝箱)回复于 2002-08-08 18:38:23 得分 0

#include   <memory>  
   
  std::auto_ptr<int>   foo()  
  {  
  std::auto_ptr<int>   __ap(new   int);  
  return   __ap;//1.   ok,   auto_ptr   can   copy   const   temporary  
  }  
   
  void   foo2(   std::auto_ptr<int>   )  
  {  
  }  
   
  int   main()  
  {  
  const   std::auto_ptr<int>   __cp   =   foo();  
  std::auto_ptr<int>   __p   =   foo();  
  foo2(   __p   );//2.   ok,   auto_ptr   can   copy   non   const   object  
  foo2(   __cp   );//3.   error,   auto_ptr   can   not   copy   const   bject  
  }  
   
  auto_ptr_ref     是   auto_ptr   的实现细节,是一个诡计。如果不能够理解这个诡计也没有关系,只要明白为什么要使用这个诡计就可以了,这个诡计就是为了同时满足上例中的   1.2.3   。不幸的是,并不是所有的编译器都能够施展这个诡计的,比如VC6.0就不行,所以在VC6.0下使用auto_ptr的同志们可要多长个心眼呀。  
   
  Top

4 楼cber(cber)回复于 2002-08-11 12:58:46 得分 0

ft,最后up一次  
   
  再次对不能回复的mail地址表示不满Top

相关问题

  • auto_ptr问题.
  • to susu_0807(令狐冲)
  • auto_ptr的问题
  • vector中能放auto_ptr吗?
  • 请教!auto_ptr的使用
  • 关于 auto_ptr 的 operator=
  • 问关于auto_ptr和auto_ptr_ref的问题
  • 送分给:susu_0807(令狐冲)
  • (令狐冲)前辈请看!
  • auto_ptr_ref<T>干什么用的?

关键词

  • smart
  • 函数
  • 指针
  • stl
  • 代码
  • 内存
  • release
  • point
  • ptr
  • auto

得分解答快速导航

  • 帖主:cber
  • anrxhzh

相关链接

  • C/C++ Blog
  • C/C++类图书
  • C/C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo