c++ unique_ptr、shared_ptr

unique_ptr 概述:

  • c++ 11模板库的<memory>头文件中定义的智能指针,即 unique_ptr 模板,用于自动释放 new 动态分布的内存空间。
  • 只要将 new 运算符返回的指针 ptr 交给一个 unique_ptr 对象托管,就不必写 delete ptr 语句,托管 ptr 指针的 unique_ptr 对象在消亡时会自动执行 delete ptr。
  • unique_ptr 对象能像指针 ptr 一样使用, *unique_ptr 就是 *ptr。

shared_ptr 与 unique_ptr 与有以上共同的特性,两者的区别在于:

  • unique_ptr 不可以进行拷贝和赋值操作,每个unique_ptr对象都是原始指针的唯一所有者
  • shared_ptr 可以进行拷贝和赋值操作,每个 shared_ptr 都会记录它所指向对象的个数,一般称之为引用计数。当进行拷贝操作时他们所指向的对象的引用计数都会增加,一旦一个shared_ptr的引用计数变为0,它就会自动释放自己所管理的对象。

示例:  

class Test {
public:
    int value = 666;
    explicit Test()
    {
        std::cout << "Test();" << std::endl;
    }

    virtual ~Test() {
        std::cout << "virtrual ~Test();" << std::endl;
    }
};

// unique_ptr 禁用了拷贝构造函数和赋值操作函数, 每个unique_ptr对象都是原始指针的唯一所有者
// unique_ptr(const unique_ptr&) = delete;
// unique_ptr& operator=(const unique_ptr&) = delete;

int main()
{
    Test* test = new Test();
    std::unique_ptr<Test> ptr1(test);
    ptr1 = std::make_unique<Test>(); // 推荐使用 make_unique 创建对象,而非 new
    // std::unique_ptr<Test> ptr4(test); 会产生运行时错误,程序结束时会重复释放导致段错误
    // std::unique_ptr<Test> ptr4 = ptr1; 编译错误,禁用了赋值操作函数
    // std::unique_ptr<Test> ptr4(ptr1); 编译错误,禁用了拷贝构造函数
    ptr1.reset(new Test()); // 先调用析构函数删除旧对象,再调用构造函数生成新对象
    std::unique_ptr<Test> ptr2 = std::move(ptr1); // 将 ptr1 指向内存指针的所有权交给 ptr2 , ptr1 置为 nullptr
    Test* ptr3 = ptr2.get(); // get() 获取 ptr2 指向 Test 的内存指针
    std::cout << ptr3->value << std::endl;
    Test* last = ptr2.release(); // 释放 ptr2 对指针的所有权,ptr2置空,返回内存指针,需要 delete 手动释放内存空间
    if (ptr2 == nullptr) {
        std::cout << "ptr2 is nullptr" << std::endl;
    }
    std::cout << last->value << std::endl;
    delete last;
    // 当智能指针 unique_ptr 拥有内存指针的所有权时,程序退出会自动调用析构函数释放内存空间
    return 0;
}

// 输出如下:
// Test();
// Test();
// virtrual ~Test();
// Test();
// virtrual ~Test();
// 666
// ptr2 is nullptr
// 666
// virtrual ~Test();
原文地址:https://www.cnblogs.com/tongyishu/p/13373099.html