auto_ptr的设计动机
C++标准程序库提供的auto_ptr是一种智能型指针(smart pointer),帮助程序员防止“被异常抛出时发生资源泄露”。
函数的操作经常依以下模式进行:
1.获取一些资源
2.执行一些操作
3.释放所获取的资源
如果一开始所获取的资源被绑定于局部对象(local objects)身上,当函数退出时,他们的析构函数(destructor)被调用,从而自动释放这些资源。然而事情不总是这么顺利,如果资源是以显示手法获得,而且没有绑定在任何对象身上,那就必须以显示的手法释放。这种情形通常发生在指针身上。
一个典型的例子就是运用new 和 delete 来产生和销毁对象:
void f() { ClassA *ptr=new ClassA; //create an object explicitly ... //perform some operations delete ptr; //clean up(destory the object explicitly) }
也许你尚未意识到,这个函数其实是一系列麻烦的根源。一个显而易见的问题是,当我们忘记delete时,特别是函数中间存在return语句时,然而真正的麻烦常常发生在更隐晦的地方,那就是当异常发生时我们所要面临的灾难。函数闪退,delete不会被调用。导致内存遗失,或更一般滴说资源遗失。
防止这种情况的一种解决方法是扑捉所有异常,例如:
void f() { ClassA* ptr=new ClassA; //create an object explicitly try{ ... //perform some operations } catch(..){ //for any exception delete ptr; //- clean up throw; //rethrow the exception } delete ptr; //clean up on normal end }
你看,这种方法是何等麻烦,此外还可能需要更多的catch语句。这并不是优良的编程风格,复杂容易出错,必须尽量避免。
如果使用智能指针,情况大不相同。这个智能指针应当保证,无论在何种情形下,只要自己被摧毁,就一定连带释放其所指的资源。而由于智能型指针本来就是区域变量。所以无论是正常退出,还是异常退出,只要函数退出,它就一定会被销毁。auto_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 }
不在需要delete,也不在需要catch了。auto_ptr的接口与一般指针相似:operator*用来提取所指对象,operator->用来指针对象的成员。然后所有指针算术(包括++)都没有定义(这可能是好事,因为指针算术是一个大麻烦)。
注意:auto_ptr<>不允许你使用一般指针惯用的赋值(assign)初始化方式。你必须使用数值来完成初始化:
std::auto_ptr<ClassA> ptr1(new ClassA); //Ok std::auto_ptr<ClassA> ptr2 = new ClassA; //ERROR
author:panzg
time:2013.10.27