zoukankan      html  css  js  c++  java
  • 深入学习c++--智能指针(三) unique_ptr

    1. 几种智能指针

    1. auto_ptr: c++11中推荐不使用他(放弃)

    2. shared_ptr: 拥有共享对象所有权语义的智能指针 

    3. unique_ptr: 拥有独有对象所有权语义的智能指针 

    4. weaked_ptr: 到 std::shared_ptr 所管理对象的弱引用 

    1.1 unique_ptr

    参考:https://zh.cppreference.com/w/cpp/memory/unique_ptr

    • std::unique_ptr 是通过指针占有并管理另一对象,并在 unique_ptr 离开作用域时释放该对象的智能指针

    • 在下列两者之一发生时用关联的删除器释放对象:

      • 销毁了管理的 unique_ptr 对象

      • 通过 operator= 或 reset() 赋值另一指针给管理的 unique_ptr 对象。

    • 通过调用 get_deleter()(ptr) ,用潜在为用户提供的删除器释放对象。默认删除器用 delete 运算符,它销毁对象并解分配内存。

    • unique_ptr 亦可以不占有对象,该情况下称它为空 (empty)

    • std::unique_ptr 有两个版本:

      • 管理个对象(例如以 new 分配)

      • 管理动态分配的对象数组(例如以 new[] 分配)

    1.2 注意

    • 只有非 const 的 unique_ptr 能转移被管理对象的所有权给另一 unique_ptr 。若对象的生存期为 const std::unique_ptr所管理,则它被限定在创建指针的作用域中。

    •  std::unique_ptr 常用于管理对象的生存期,包含:

      • 通过正常退出经由异常退出两者上的 受保证删除,提供异常安全,给处理拥有动态生存期的对象的类和函数

      • 传递独占的拥有动态生存期的对象的所有权到函数

      • 从函数获得独占的拥有动态生存期对象的所有权

    1.3 使用方式

    • unique_ptr: 在某一个特定时刻,只有一个unique_ptr管理资源
    • 拷贝构造函数和 "=" 对于unique_ptr不存在
    • // UniqueObjectPtr(const UniqueObjectPtr&) = delete
      // UniqueObjectPtr(UniqueObjectPtr&&) = default
      // 把 资源转移给别人

    #include <iostream>
    #include <cassert>
    #include <memory>
    using namespace std;
     
    class Object
    {
    public:
        Object(int id) : m_id(id) {
            std::cout << "init obj " << m_id << std::endl;
        }    
        ~Object() {
            std::cout << "bye bye " << m_id << std::endl;
        }
        int id() const {
            return m_id;
        }
    private:
        int m_id;
    };
    
    typedef unique_ptr<Object> UniqueObjectPtr;
    typedef std::shared_ptr<Object> ObjectPtr;
    
    void print(const UniqueObjectPtr& obj)
    {
        
    }
    
    void Transfer(UniqueObjectPtr obj)
    {
        cout << obj->id() << endl;
    }
    
    // unique_ptr: 在某一个特定时刻,只有一个unique_ptr管理资源
    // 拷贝构造函数和 "=" 对于unique_ptr不存在 
    void uniquePtr()
    {
        UniqueObjectPtr obj(new Object(1));
        auto p = obj.get();
        if (p) {
        }
        //better
        if (obj) {
        }
        
        //operator -> *
        cout << p->id() << " " << obj->id() << " " << (*obj).id() << endl;
        print(obj);
        
        p = obj.release();        // 自身不再管理该指针 
        delete p;                 // 之后,该指针可以按常规指针处理   
        
        obj.reset();              // 把以前管理的资源调用析构 
        obj.reset(new Object(2)); // 1. obj.reset(); 2. 管理新的指针
        
        // UniqueObjectPtr(const UniqueObjectPtr&) = delete
        // UniqueObjectPtr(UniqueObjectPtr&&) = default 
        // 把 资源转移给别人  
        Transfer(std::move(obj));  // 一个unique_ptr的值, 接收右值的引用 
        
        // 违反unique_ptr规则,上一行用函数形参传入unique_ptr,对于原有obj 已经不在管理他的资源,obj掌握一个空指针
        assert(obj == nullptr); 
    //    cout << obj->id() << endl;  
        
        // 某种情况下, 可能有其他类型也需要使用该 资源 
        // 转移成其他 智能指针 
        obj.reset(new Object(4)) ;
        // 只能右值传入 
        ObjectPtr sharedObj(std::move(obj));
        assert(obj == nullptr);                    // obj不再管理资源 
        
    }
    
    int main()
    {
        
        uniquePtr();
        return 0;
    }

     

  • 相关阅读:
    递归判断字符串是否为回文
    原码,补码,反码
    Java语言程序设计2019.9.16
    四则运算---根据用户要求输出计算题源代码
    学生成绩管理系统-JAVA语言测试
    暑假生活第八周
    暑假生活第七周
    暑假生活第六周
    POJ 2400 Supervisor, Supervisee(KM二分图最大权值匹配)题解
    POJ 2226 Muddy Fields(最小点覆盖)题解
  • 原文地址:https://www.cnblogs.com/douzujun/p/10803484.html
Copyright © 2011-2022 走看看