C++11之智能指针与c++98的auto_ptr

c++11里面的unique_ptr与98版里面的auto_ptr较为相似。都是独占性智能指针。但其却可以指向数组

先看看<<深入应用C++11:代码优化与工程级应用>>里祁宇的解说:


wKioL1aJCcbzsvH0AAJeVowJhbM991.png

wKioL1aJCciT_Q7OAAKXXnA7Odo388.png



我们关心的,reset, release,get用法如下,与auto_ptr还是一样:

1,release :相当于get()那样返回原始指针然后再转移所有权。并没有释放。自己变成null。 

2,get: 只是返回原始指针

3,reset:原来unique_ptr或auto_ptr指向的对象将会析构,智能指针指向新对象。 

  参数一般是p.release()这种形式。




#include <memory>
#include <iostream>
using namespace std;
class UNP
{
public:
    UNP(int ii)
    {
        i = ii;
        cout<<"constructor:"<<i<<endl;
    }
    ~UNP()
    {
        cout<<"destructor:"<<i<<endl;
    }
private:
    int i;
};
std::unique_ptr<UNP> uniptr()
{
   //unique_ptr构造
//    unique_ptr<int> u_i10;
//    u_i10.reset(new int(10)); //方法1:先设空,再reset

//    unique_ptr<int> u_i11(new int(11)); //方法2:直接赋值构造

    UNP* k = new UNP(2);
    std::unique_ptr<UNP> u_i2(k); //方法3:普通指针构造,直接管理k

    unique_ptr<UNP> u_i1(new UNP(1));
    u_i1.reset(u_i2.release()); //方法4,用另一个unique_ptr构造,u_i1原来指向的对象UNP(1) 现在会析构,u_i1帮u_i2管理,
                                          // u_i2变成空,  注意u_i2.release()会使u_i2变成空。

    unique_ptr<UNP> u_i3(new UNP(3));
    u_i3 = std::move(u_i1); //方法5,所有权转移(通过移动语义),同方法4,UNP(3)会析构,u_i3帮u_i1管理,u_i1变成空
    return u_i3;

//    int *p_i = u_i2.release(); //释放所有权,u_i2变成空
//    unique_ptr<string> u_s(new string("abc"));
//    unique_ptr<string> u_s2 = std::move(u_s); //所有权转移(通过移动语义),u_s所有权转移后,变成“空指针”
//    u_s2=nullptr;//显式销毁所指对象,同时智能指针变为空指针。与u_s2.reset()等价
}

int main()
{
    unique_ptr<UNP> a = std::move(uniptr());
    a = nullptr; //UNP(2)已析构,不需等到main完结,显式销毁所指对象,同时智能指针变为空指针。与a.reset()等价
    return 0;
}


换成auto_ptr效果是一样的。
#include <memory>
#include <iostream>
using namespace std;
class UNP
{
public:
    UNP(int ii)
    {
        i = ii;
        cout<<"constructor:"<<i<<endl;
    }
    ~UNP()
    {
        cout<<"destructor:"<<i<<endl;
    }
private:
    int i;
};
std::auto_ptr<UNP> uniptr()
{
   //unique_ptr构造
//    unique_ptr<int> u_i10;
//    u_i10.reset(new int(10)); //方法1:先设空,再reset

//    unique_ptr<int> u_i11(new int(11)); //方法2:直接赋值构造

    UNP* k = new UNP(2);
    std::auto_ptr<UNP> u_i2(k);
//    std::unique_ptr<UNP> u_i2(k); //方法3:普通指针构造,直接管理k

    std::auto_ptr<UNP> u_i1(new UNP(1));
//    unique_ptr<UNP> u_i1(new UNP(1));
    u_i1.reset(u_i2.release()); //方法4,用另一个unique_ptr构造,u_i1原来指向的对象UNP(1) 现在会析构,u_i1帮u_i2管理,
                                          // u_i2变成空,  注意u_i2.release()会使u_i2变成空。

    std::auto_ptr<UNP> u_i3(new UNP(3));
//    unique_ptr<UNP> u_i3(new UNP(3));
    u_i3 = std::move(u_i1); //方法5,所有权转移(通过移动语义),同方法4,u_i3原来指向的UNP(3)会析构,u_i3帮u_i1管理,u_i1变成空
    return u_i3;

//    int *p_i = u_i2.release(); //释放所有权,u_i2变成空
//    unique_ptr<string> u_s(new string("abc"));
//    unique_ptr<string> u_s2 = std::move(u_s); //所有权转移(通过移动语义),u_s所有权转移后,变成“空指针”
//    u_s2=nullptr;//显式销毁所指对象,同时智能指针变为空指针。与u_s2.reset()等价
}

int main()
{
{
    auto_ptr<UNP> a = std::move(uniptr());

    }
    return 0;
}

 


可见,它们就只有两个差别:

1,unique_ptr可以指向数组, auto_ptr不可以。

2,unique_ptr可以通过设置nullptr显示销毁对象, auto_ptr不可以。



什么时候用release,什么时候用get()


当有auto_ptr或unique_ptr对象接收所有权的时候用release,没有的时候用get();


reset接收的如果是智能指针,那么是另一个智能指针release返回的对象。


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