1.智能指针的由来
先看下面代码:
void remodel(std::string &str)
{
std::string *ps = new std::string(str);
if(werid_thing())
{
throw exception();
}
str =*ps;
delete ps;
return;
}
当remodel( )这样的函数终止(不管是正常终止,还是由于出现了异常而终止),本地变量都将从栈内存中删除——因此指针 ps占据的内存将被释放。如果ps 指向的内存也被释放,那该有多好啊。如果ps有一个析构函数,该析构函数将在ps 过期时释放它指向的内存。因此,ps 的问题在于,它只是一个常规指针,不是有析构函数的类对象。如果它是对象,则可以在对象过期时,让它的析构函数删除指向的内存。这正是auto_ptr、unique_ptr和 shared ptr背后的思想。模板auto_ptr是C++98提供的解决方案,C++11已将其摒弃,并提供了另外两种解决方案。然而,虽然auto_ptr被摒弃,但它已使用了多年;同时,如果您的编译器不支持其他两种解决方案,auto ptr将是唯一的选择。
2.智能指针的使用
这三个智能指针模板(auto_ptr. unique_ptr和 shared_ptr)都定义了类似指针的对象,可以将new获得(直接或间接)的地址赋给这种对象。当智能指针过期时,其析构函数将使用delete 来释放内存。因此,如果将new返回的地址赋给这些对象,将无需记住稍后释放这些内存:在智能指针过期时,这些内存将自动被释放。下图说明了auto_ptr和常规指针在行为方面的差别; share_ptr和unique ptr的行为与auto_ ptr相同。
要创建智能指针对象,必须包含头文件 memory,该文件模板定义。然后使用通常的模板语法来实化所需类型的指针。
应使用哪种智能指针呢﹖如果程序要使用多个指向同一个对象的指针,应选择shared_ptr。这样的情况包括:有一个指针数组,并使用一些辅助指针来标识特定的元素,如最大的元素和最小的元素;两个对象包含都指向第三个对象的指针;STL容器包含指针。很多STL算法都支持复制和赋值操作,这些操作可用于shared_ptr,但不能用于unique_ptr(编译器发出警告〉和auto_ptr(行为不确定)。如果您的编译器没有提供shared _ptr,可使用Boost库提供的shared ptr。
如果程序不需要多个指向同一个对象的指针,则可使用unique ptr。如果函数使用new分配内存,并返回指向该内存的指针,将其返回类型声明为unique_ptr是不错的选择。这样,所有权将转让给接受返回值的unique_ptr,而该智能指针将负责调用delete。可将unique_ptr存储到STL容器中,只要不调用将一个unique_ptr复制或赋给另一个的方法或算法(如 sort( ))。例如,可在程序中使用类似于下面的代码段,这里假设程序包含正确的include和 using 语句。