C++---智能指针(auto_ptr、unique_ptr、shared_ptr)

智能指针

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
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工作,像旁观者那样观测资源的使用情况。它的构造和析构不会引起引用记数的增加或减少.。

你可能感兴趣的:(C++)