智能指针_通用工具_STL

C++ STL提供的auto_ptr是一种智能型指针(smart pointer),帮助程序员防止“被异常抛出时发生资源泄露”。一下就auto_ptr的设计动机、auto_ptr的拥有权转移和auto_ptr的运用方面进行阐述。


一,auto_ptr的设计动机

1,获取一些资源。

2,执行一些动作。

3,释放所获取的资源

一个典型的例子是使用new和delete来产生和摧毁对象:

void f()
{
   ClassA* ptr=new ClassA;
   ...
   delete ptr;
}

然而经常会忘掉delete动作,特别是当函数中存在return时更是如此。更隐晦的是当异常发生时,函数将立刻退离而调用不到尾端的delete语句。如:

void f()
{
     ClassA* ptr=new ClassA;
     try{
         ....}
       catch(...){
            delete ptr;
             throw;
        }
        delete ptr;
}

auto_ptr是这样一种指针:它是“它所指向对象”的拥有者(owner)。所以当身为对象拥有者的auto_ptr被摧毁时,该对象也将被摧毁。auto_ptr要求一个对象智能有一个拥有者,严禁一物二主。

下面是上例改写后的版本:

//header file for auto_ptr
#include <memory>

void f()
{
    //create and initialize an auto_ptr
    std::auto_ptr<ClassA> ptr(new ClassA);
    ...     //perform some operations
}


不再需要catch,也不再需要delete了。


二,auto_ptr拥有权(ownership)的转移

 auto_ptr的copy构造函数和assignment操作符将对象拥有权交出去。如:

//initialize an auto_ptr with a new object
std::auto_ptr<ClassA> ptr1(new ClassA);

//copy the auto_ptr
//-transfers ownership from ptr1 to ptr2
std::auto_ptr<ClassA> ptr2(ptr1);


std::auto_ptr<ClassA> ptr1(new ClassA);
std::auto_ptr<ClassA> ptr2;
ptr2=ptr1;  //assign the auto_ptr transfers ownership from ptr1 to ptr2

三, auto_ptr的缺陷

看例子:

//this is a bad example
template <class T>
void bad_print(std::auto_ptr<T> p)  //p gets the ownership of passed argument
{
   //does p own an object?
    if(p.get()==NULL){
       std::cout<<"NULL";
    }
    else{
      std::cout<<*p;
    }
}  //Oops, existing deletes the objects to witch p regers

只要有一个auto_ptr被当做参数,放进这个bad_ptr() 函数,它所拥有的对象(如果有的话)就一定会被删除。因为作为参数的auto_ptr会将拥有权转交给参数p,而当函数退出时,会删除p所拥有的对象。这恐怕不是程序员所希望的,最终会引起致命的执行期错误:

std::auto_ptr<int> p(new int);
*p=42;    //change value to which p refers
bad_print(p);   //Oops,deletes the memory to which p refers
*p=18;    //runtime error
考虑到auto_ptr 的概念,我们可以用constant reference,向函数传递拥有权。事实上,constant reference 无法交出拥有权,无法变更constant reference的拥有权。
const std::auto_ptr<int> p(new int);
*p=42;   //change value to which p regers
bad_print(p);   //compile-time error
*p=18;    //Ok
这一方案使得auto_ptr变得安全些。很多接口在需要内部拷贝时,都通过constant reference 获得原值。事实上,C++ STL的所有容器都如此,大致像这样:
template <class T>
void container::insert(const T& value)
{
     .....
     x=value;
     .....
}

其实,在这里关键字const 并非意味着你不能更改auto_ptr所拥有的对象,而是说明你不能更改auto_ptr的拥有者。例如:

 
 
std:auto_ptr<int> f()
{
const std::auto_ptr<int> p(new int); //no ownership transfer possible
std::auto_ptr<int> q(new int); //ownership transfer possible
*p=42; //OK, change value to which p refers
bad_print(p); //compile time error
*p=*q; //OK, change value to which p refers
p=q; //compile time error
return p;
}
如果使用const auto_ptr作为参数,对新对象的任何赋值都将导致编译器错误。就常数特性而言,const auto_ptr比较类似常数指针(T* const p),而非指向常数的指针(const T* p)---------尽管其语法上看上去比较向后者。


参考:The C++ Standard Library (A Tutorial and Reference)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值