智能指针
void fun(string str)
{string ps = new string(str);str = ps;return;
}
当函数调用时,都会分配堆中的内存,但没有回收,会导致内存泄漏。这种情况在 return 之前加上 free 就可以了。
void fun(string str)
{string ps = new string(str);...if(weird_fhing())throw exception();str = ps;delete ps;return;
}
当出现异常时,delete 将不执行,导致内存泄漏。
当函数终止时,本地变量将从栈内存中删除,指针 ps 的内存将被释放,但是 ps 指向的堆上的内存并没有被释放,
智能指针:创建一个指针对象,其中有释放指向堆内存的析构函。
auto_ptr
使用 auto_ptr 智能指针
#include<memory> // 包含头文件 memory
void fun(string str)
{auto_ptr<string> ps = new string(str); // 将指向 string 的指针替换为指向 string 的智能指针对象str = ps;return;
}
shared_ptr
auto_ptr<string> ps (new string("aaa"));
auto_ptr<string> vocation;
vocation = ps;
如果 ps 和 vocation 是常规指针。这是不能接受的,因为程序将试图删除同一个对象两次——一次是 ps 过期时,一次是 vocation 过期时。为了避免这种情况,有以下方法:
定义赋值运算符:执行深拷贝,这样两个指针将指向不同的对象,其中一个对象是另一个对象的副本。
建立所有权概念:对于特定对象只能一个智能指针可以拥有他,这样只有拥有对象的智能指针的析构函数能删除该对象,然后,让赋值操作转让权限。这就是用于 auto_ptr 和 unique_ptr 的策略,但是 unique_ptr 更严格。
创建智能更高的指针:跟踪引用特定对象的智能指针数。即引用计数。shared_ptr。
unique_ptr 和 auto_ptr
auto_ptr<string> p1(new string("aaa"));
auto_ptr<string> p2;
p2 = p1;
p2 接管 string 对象所有权后,p1 的多有权将被剥夺。但是如果程序试图使用 p1,这就会出现错误。
如果使用 unique_ptr 在 p2 = p1 时,编译阶段就会报错, 相对更安全。
程序试图将一个 unique_ptr 赋给另一个时,如果源 unique_ptr 是一个临时的右值,编译器允许这样做,若果 unique_ptr 将存在一段时间将会出错。
unique_ptr<string> p1(new string "aaa");
unique_ptr<string> p2;
p2 = p1; //not allowed
unique_ptr<string> p3;
p3 = unique_ptr<string>(new string"aaa"); //allowed
unique_ptr 有一个可用于数组的变体。
模板 auto_ptr 使用 delete 而不是 delete[ ],因此只能与 new 一起用,不能与new[ ]一起使用。
unique_ptr 有使用 new[ ] 和 delete[ ] 的版本。
weak_ptr
weak_ptr是为了配合shared_ptr而引入的一种智能指针,它更像是shared_ptr的一个助手而不是智能指针,因为它不具有普通指针的行为,没有重载operator*和->,它的最大作用在于协助shared_ptr工作,像旁观者那样观测资源的使用情况。它的构造和析构不会引起引用记数的增加或减少.。