auto_ptr模板类 (智能指针)

auto_ptr模板类

     auto_ptr模板定义了类似指针的对象,可以将new获得(直接或间接)的地址赋给这种对象。当auto_ptr对象过期时,其析构函数将使用delete来释放内存。

 

     要创建auto_ptr对象,必须包含头文件memory。使用通常的模板句法来实例化所需类型的指针。模板中包括:

 

     template<class X>
         class auto_ptr
         { public:
              explicit auto_ptr(X * p = 0) throw();
           ... };

 

     throw()意味着构造函数不引发异常。因此,请求X类型的auto_ptr将获得一个指向X类型的auto_ptr:

     auto_ptr<double> pd(new double);    // an auto_ptr to double
                                                                 // (use in place of double *)

     auto_ptr<string> ps(new string);    // an auto_ptr to string
                                                             // (use in place of string *)

     上述中new double是new返回的指针,指向新分配的内存块。它是auto_ptr<double>构造函数的参数,即它是对应于原型中形参 X* p 的实参。

 

范例:
#include <memory>
void remodel (string & str)
{ auto_ptr<string> ps(new string(str));
  ...
  if (weird_thing())
      throw exception();
  str = *ps;
  //delete ps: NO LONGER NEEDED
  return;
}

 

     auto_ptr的构造函数是显示的,因此不存在从指针到auto_ptr对象的隐式类型转换:

auto_ptr<double> pd;
double *p_reg = new double;
pd = p_reg;                                       // not allowed(implicit conversion)
pd = auto_ptr<double> (p_reg);      // allowed(explicit conversion)
auto_ptr<double> pauto = p_reg;   // not allowed(implicit conversion)
auto_ptr<double> pauto (p_reg);
   // allowed(explicit conversion)

 

     auto_ptr是一种智能指针(smart pointer)——类似于指针,但特性比指针更多。


     auto_ptr类被定义为在很多方面与常规指针类似。例如,如果ps是一个auto_ptr,则可以对它执行解除引用操作(*ps)和递增操作(++ps),用它来访问结构成员(ps->puffIndex),将它赋给指向相同类型的常规指针。还可以将auto_ptr赋给另一个同类型的auto_ptr,但将引发一个问题,请看下面“auto_ptr赋值问题”。

 

auto_ptr的注意事项

     由于auto_ptr模板使用的是delete,因此它只能与new一起使用:

     auto_ptr<int> pi (new int[200]);  //NO
     这将引发错误。

 

     可以复制头文件memory中的auto_ptr模板,然后对其进行修改,使之使用delete[]。

 

     下述代码将delete操作符用于非堆内存,而引发错误:

     string vacation("I wandered lonely as a cloud.");
     auto_ptr<string> pvac (&vacation);
     //NO

 

     警告: 只能对new分配的内存使用auto_ptr对象,而不要对由new[]分配的或者通过声明变量分配的内存使用它。

 

auto_ptr赋值问题

 

auto_ptr<string> ps (new string("I reigned lonely as a cloud.") );
auto_ptr<string> vocation;
vocation = ps;

 

     两个指针将指向同一个string对象,其中一个是另一个的拷贝。当ps和vocation都过期时,程序将试图删除同一个对象两次。

 

解决办法:

(1) 定义赋值操作符,使之执行深度复制。这样两个指针将指向不同的对象,其中的一个对象是另一个对象的拷贝。

 

(2) 建立所有权(ownership)概念,对于特定的对象,只能有一个智能指针可拥有它。智能指针的构造函数只能删除该智能指针拥有的对象。并使赋值操作转让所有权。这就是用于auto_ptr的策略。

 

(3) 创建智能更高的指针,跟踪引用特定对象的智能指针数。这被称为引用计数(reference counting)。例如,赋值时,计数器加1;指针过期时,计数将减1。仅当最后一个指针过期时,delete才被调用。

 

    (同样的策略也适用于复制构造函数)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值