当需要使用智能指针时,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);