指向的指针的生命周期是有限的,除了生命周期范围外将会被释放(调用该指向类型的析构函数)。
unique_ptr没有copy构造函数,不支持普通的拷贝和赋值操作。
int main()
{
// 创建一个unique_ptr实例
unique_ptr<int> pInt(new int(5));
unique_ptr<int> pInt2(pInt); // 报错
unique_ptr<int> pInt3 = pInt; // 报错
}
只要unique_ptr指针创建成功,其析构函数都会被调用。确保动态资源被释放。
Example
Run this code
#include <iostream> #include <memory> struct Foo { // object to manage Foo() { std::cout << "Foo ctor\n"; } Foo(const Foo&) { std::cout << "Foo copy ctor\n"; } Foo(Foo&&) { std::cout << "Foo move ctor\n"; } ~Foo() { std::cout << "~Foo dtor\n"; } }; struct D { // deleter D() {}; D(const D&) { std::cout << "D copy ctor\n"; } D(D&) { std::cout << "D non-const copy ctor\n";} D(D&&) { std::cout << "D move ctor \n"; } void operator()(Foo* p) const { std::cout << "D is deleting a Foo\n"; delete p; }; }; int main() { std::cout << "Example constructor(1)...\n"; // 创建示例 std::unique_ptr<Foo> up1; // up1 is empty std::unique_ptr<Foo> up1b(nullptr); // up1b is empty std::cout << "Example constructor(2)...\n"; { std::unique_ptr<Foo> up2(new Foo); //up2 now owns a Foo } // Foo deleted std::cout << "Example constructor(3)...\n"; // 转移一个std::unique_ptr将会把所有权也从源指针转移给目标指针(源指针被置空)。 D d; { // deleter type is not a reference std::unique_ptr<Foo, D> up3(new Foo, d); // deleter copied, 如果 D是基本的数据类型(int \ bool ···)会报错。d作为参数会进行函数参数的传值:拷贝的参数会被创建并释放 } { // deleter type is a reference std::unique_ptr<Foo, D&> up3b(new Foo, d); // up3b holds a reference to d,原来的对象并没有被释放 } std::cout << "Example constructor(4)...\n"; { // deleter is not a reference std::unique_ptr<Foo, D> up4(new Foo, D()); // deleter moved } // std::move(): 将指针的所有权从一个unique_ptr转移给另一个unique_ptr。 unique_ptr没有支持普通的拷贝和赋值操作 std::cout << "Example constructor(5)...\n"; { std::unique_ptr<Foo> up5a(new Foo); // 构造新对象 std::unique_ptr<Foo> up5b(std::move(up5a)); // ownership transfer,up5a is empty } std::cout << "Example constructor(6)...\n"; { std::unique_ptr<Foo, D> up6a(new Foo, d); // D is copied, d作为参数会有副本出现,会被构造并析构 std::unique_ptr<Foo, D> up6b(std::move(up6a)); // D is moved std::unique_ptr<Foo, D&> up6c(new Foo, d); // D is a reference,不会构造新的对象 std::unique_ptr<Foo, D> up6d(std::move(up6c)); // D is copied } #if (__cplusplus < 201703L) std::cout << "Example constructor(7)...\n"; { std::auto_ptr<Foo> up7a(new Foo); std::unique_ptr<Foo> up7b(std::move(up7a)); // ownership transfer } #endif std::cout << "Example array constructor...\n"; { std::unique_ptr<Foo[]> up(new Foo[3]); } // three Foo objects deleted }
Output:
Example constructor(1)... Example constructor(2)... Foo ctor ~Foo dtor Example constructor(3)... Foo ctor D copy ctor D is deleting a Foo ~Foo dtor Foo ctor D is deleting a Foo ~Foo dtor Example constructor(4)... Foo ctor D move ctor D is deleting a Foo ~Foo dtor Example constructor(5)... Foo ctor ~Foo dtor Example constructor(6)... Foo ctor D copy ctor D move ctor Foo ctor D non-const copy ctor D is deleting a Foo ~Foo dtor D is deleting a Foo ~Foo dtor Example constructor(7)... Foo ctor ~Foo dtor Example array constructor... Foo ctor Foo ctor Foo ctor ~Foo dtor ~Foo dtor ~Foo dtor