zoukankan      html  css  js  c++  java
  • 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();
  • 相关阅读:
    jQuery选择器
    安装ASP.NET4.0
    自动换行的布局
    一个封装不错的 TcpClient 类
    goland 中国 caisy qq Czx123456
    由于google被墙, 一些go语言包不能下载, 可以通过Chome浏览器到这个网址下载
    在Windows 操作系统中, MySql 如何设置, 允许表名支持大小写
    websocket 的客户端 websocket-sharp
    将一个C++的AES加密算法(有向量的)翻译成C#
    AES 加密问题
  • 原文地址:https://www.cnblogs.com/tongyishu/p/13373099.html
Copyright © 2011-2022 走看看