当需要使用智能指针时,std::unique_ptr基本上应当是首选,因为默认情况下std::unique_ptr和裸指针有着相同的尺寸,且对于大多数的操作(包括提领),他们都是精确的执行了相同的指令。

std::unique_ptr实现的是专属所有权语义,其只支持移动,不支持复制,也不能将一个裸指针直接赋值给std::unique_ptr对象,编译器禁止这种隐式转换。默认的std::unique_ptr的析构函数将调用delete完成指针删除操作,当然,如果默认的析构函数不满足要求,我们也可以自定义析构函数,代码实现及运行结果如下:

class MyTest {
public:
    //自定义类构造函数
    MyTest() {
        cout << "MyTest" << endl;
    };

    //自定义类析构函数
    ~MyTest() {
        cout << "~MyTest" << endl;
    };
};

int main()
{
    {
        //std::unique_ptr的自定义析构函数,t可以为MyTest类型及其子类
        auto MyDelete = [](MyTest* t) {
            cout << "MyDelete" << endl;
            delete t;
        };
        //智能指针初始化
        std::unique_ptr<MyTest,decltype(MyDelete)> p(new MyTest, MyDelete);
    }
    return 0;
}


 当我们使用std::unique_ptr自定义析构函数时,std::unique_ptr的尺寸会有所增加,其中函数指针增加一到两个字长,函数对象包括lambda表达增加的尺寸与函数对象存储的状态个数相关。

std::unique_ptr以两个形式提供,一种是单个对象(std::unique_ptr<T>),一种是数组(std::unique_ptr<T[]>),std::unique_ptr对两种形式提供的成员函数有所不同,例如,对单个对象形式不提供索引运算符(operator[]),对数组形式不提供提领运算符(operator*和operatpr->).

最后一点,std::unique_ptr可以很方便的转换为std::shared_ptr型别,但反之则不行。例如:

//可以将std::unique_ptrz转换为std::shared_ptr
std::unique_ptr<int> u(new int);
std::shared_ptr<int> p = std::move(u);


//不可以std::shared_ptr转换为std::unique_ptr
std::shared_ptr<int> u(new int);
std::unique_ptr<int> p = std::move(u);