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

    1. 几种智能指针

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

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

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

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

    1.1 shared_ptr

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

    std::shared_ptr 是通过指针保持对象共享所有权的智能指针。多个 shared_ptr 对象可占有同一对象。下列情况之一出现时销毁对象并解分配其内存:

    • 最后剩下的占有对象的 shared_ptr 被销毁;
    • 最后剩下的占有对象的 shared_ptr 被通过 operator= 或 reset() 赋值为另一指针。
    #include <iostream>
    #include <memory>
    #include <thread>
    #include <chrono>
    #include <mutex>
    
    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 std::shared_ptr<Object> ObjectPtr;
    
    void print(ObjectPtr obj);
    void printRef(const ObjectPtr& obj);
    
    void interfaceOfSharedPtr()
    {
        ObjectPtr null;
        std::cout << "ref count is " << null.use_count() << std::endl; // 0
    
        ObjectPtr obj(new Object(1));
        std::cout << "ref count is " << obj.use_count() << std::endl;  // 1
    
        ObjectPtr obj2(obj);
        std::cout << "ref count is " << obj.use_count() << std::endl;  // 2
    
        ObjectPtr obj3 = obj;
        std::cout << "ref count is " << obj.use_count() << std::endl;  // 3
    
        obj2.reset();        // 不需要了 
        //obj2 = nullptr;    // c++11写法
        std::cout << "ref count is " << obj.use_count() << std::endl;  // 2
    
        ObjectPtr obj4;
        obj3.swap(obj4);
        //std::swap(obj3, obj4);   // 本身管理资源,引用数没有变化 
        std::cout << "ref count is " << obj.use_count() << std::endl;  // 2
    
        auto p = obj.get();
        if (p)
        {
            std::cout << "id is " << p->id() << std::endl;
        }
    
        if (obj)
        {
             std::cout << "p id is " << obj->id() << std::endl;        // operator ->
             std::cout << "ref id is " << (*obj).id() << std::endl;    // operator *
        }
    
        obj4 = nullptr;
    //   if (obj.unique())          //效率更高
    //   if (obj.use_count() == 1)  // 会有效率损失   
    
        std::cout << "only one hold ptr " << obj.unique() << std::endl;
        // 值传入 
        print(obj);
        std::cout << "ref count is " << obj.use_count() << std::endl;
    
        // 引用传入, 推荐
        printRef(obj);
    }
    
    void print(ObjectPtr obj)         // 值传入,会临时改变引用数量+1
    {
        std::cout << "count " << obj.use_count() << " id " << obj->id()
                  << std::endl;       // 3
    }
    
    void printRef(const ObjectPtr& obj)  // 引用传递不会改变引用数量
    {
        std::cout << "ref count " << obj.use_count() << " id " << obj->id()
                  << std::endl;       // 2
    }
    
    void deleteOfObject(Object* obj)
    {
        if (obj) {
            std::cout << "delete obj " << obj->id() << std::endl;
            delete obj;
        }
    }
    
    void useDeleter()
    {
        // 管理 裸指针 和 处理这个指针的函数 -- 可以管理应用delete资源,也可以管理其他类似资源
        ObjectPtr obj(new Object(2), deleteOfObject);
        ObjectPtr obj2 = obj;
    }
    
    int main()
    {
    
        interfaceOfSharedPtr();
    
        return 0;
    }
    ref count is 0
    init obj 1
    ref count is 1
    ref count is 2
    ref count is 3
    ref count is 2
    ref count is 2
    id is 1
    p id is 1
    ref id is 1
    only one hold ptr 1
    count 2 id 1
    ref count is 1
    ref count 1 id 1
    bye bye 1

  • 相关阅读:
    动与静
    ASP.NET 2.0 Membership
    又是asp.net 2.0的一个奇怪异常
    Cool tool !ASP.NET AJAX JavaScript Class Browser
    UserFul Methods
    中秋快乐
    Windows Vista RTM
    asp.net 2.0 下的表单验证Cookieless属性
    DataTable 内部索引已损坏:"4"
    asp.net 2.0 用户管理功能结构
  • 原文地址:https://www.cnblogs.com/douzujun/p/10793614.html
Copyright © 2011-2022 走看看