zoukankan      html  css  js  c++  java
  • C++ 之实现自己的 unique_ptr

    1. 几个基本成员函数的作用:

    u.reset()   释放u指向的对象
    u.reset(q)  如果提供了内置指针q,就令u指向这个对象 
    u.reset(nullptr) 将 u 置为空
    u.release()   u 放弃对指针的控制权,返回指针,并将 u 置为空
    

    2. 一些规则:

    1. 某个时刻只能有一个unique_ptr 指向一个给定的对象。当它销毁时,它所指向的对象也会被销毁。
    2. 初始化 unique_ptr 只能采用直接初始化的方式 (explicit 关键字)
    3. 不支持复制构造与赋值操作
    4. 在创建或者是reset一个具有删除器的unique_ptr 时,必须提供删除器
    5. 不支持拷贝与赋值的规则有一个例外,那就是我们可以拷贝或者赋值一个将要被销毁的unique_ptr(右值引用) ,比如:
    /* 从函数返回一个unique_ptr */
    unique_ptr<int> clone(int p ){
        return unique_ptr<int>(new int(p));
    }
    /* 返回一个局部对象的拷贝 */
    unique_ptr<int> clone(int p ){
        unique_ptr<int> ret(new int (p));
        return ret ;
    }
    1. noexcept :在C++11中,声明一个函数不可以抛出任何异常使用关键字noexcept.

    3. unique_ptr使用场景

    1、为动态申请的资源提供异常安全保证
    2、返回函数内动态申请资源的所有权
    3、在容器中保存指针
    4、管理动态数组
    5、作为auto_ptr的替代品 
    
                 /*unique_ptr.h 文件 */
    #ifndef _UNIQUE_PTR_H
    #define __UNIQUE_H
    class Delete {   
    public:
        template<typename T>
        void operator()(T *p) const {
            delete  p;
        }
    };
    template<typename T,typename D = Delete >
    class unique_ptr {
    public:
        explicit unique_ptr(T *pp = nullptr ,const D &dd= D() )
            :un_ptr(pp),del(dd)
            {  
            }
        ~unique_ptr() { 
            del(un_ptr); 
        } 
        /* 不支持拷贝与赋值   */
        unique_ptr(const unique_ptr&) = delete ;
        unique_ptr& operator=(const unique_ptr& ) = delete ;
    
        /*可以拷贝或者赋值一个将要被销毁的 unique_ptr(右值引用)*/
        unique_ptr( unique_ptr&& right_value):
            un_ptr(right_value.un_ptr),del(std::move(right_value.del)) {
            right_value.un_ptr = nullptr ;
        }
        unique_ptr& operator=( unique_ptr&& right_value ) noexcept {
            if(this != &right_value ){
                std::cout << "operator && right_value " << std::endl ;
                del(*this);
                un_ptr = right_value.un_ptr;
                del = std::move(right_value.del);
                right_value.un_ptr =  nullptr ;
            }
            return *this ;
        }
        //u.release()   u 放弃对指针的控制权,返回指针,并将 u 置为空
        T* release(){ 
            T *tmp = un_ptr ;
            un_ptr = nullptr ;
            return  tmp  ;
        }
        /*
        u.reset()   释放u指向的对象
        u.reset(q)  如果提供了内置指针q,就令u指向这个对象 
        u.reset(nullptr) 将 u 置为空
        */
        void reset(){  del(un_ptr); }
        void reset(T* q  ){ 
            if( un_ptr ){
                del(un_ptr) ;
                un_ptr = q ;
            }
            else 
                un_ptr = nullptr ; 
        }
        void swap(unique_ptr &other ) noexcept {
            using std::swap ; 
            swap( un_ptr,other.un_ptr );
            swap(del,other.del) ;
        } 
        T* get() { return un_ptr ; }
        D& get_deleter(){ return  del ; }
        T& operator*()  { return *un_ptr ; }
        T* operator->() { return  un_ptr ; }
    private:
        T *un_ptr = nullptr ;
        D del ;
    };
    #endif
                /*    main.cpp 文件  */
    #include <iostream>
    #include <string>
    //#include"shared_ptr.h"
    #include "unique_ptr.h"
    #include"DebugDelete.h"
    #include <assert.h>
    struct Foo {
        Foo() { std::cout << "Foo()
    "; }
        ~Foo() { std::cout << "~Foo()
    "; }
        Foo(const Foo&) { std::cout << "Foo copy ctor
    "; }
        Foo(Foo&&) { std::cout << "Foo move ctor
    "; }
    };
    struct Fooo {
        Fooo(int n = 0) noexcept : bar(n) { std::cout << "Fooo: constructor, bar = " << bar << '
    '; }
        ~Fooo() { std::cout << "Fooo: destructor, bar = " << bar << '
    '; }
        int GetBar() const noexcept { return bar; }
    private:
        int bar;
    };
    struct D {
        void bar() { std::cout << "Call deleter D::bar()...
    "; }
        void operator()(Foo* p) const
        {
            std::cout << "Call delete from function object...
    ";
            delete p;
        }
    };
    using namespace std ;
    int main()
    {
        unique_ptr<string> p1(new string("Shengxi-Liu"));
        cout << *p1 << endl ;
          {
            std::cout << "======================
    unique_ptr constructor:
    ";
            unique_ptr<Foo> up1;
            unique_ptr<Foo> up1b(nullptr);
            unique_ptr<Foo> up2(new Foo);
    
            DebugDelete d;
            unique_ptr<Foo, DebugDelete> up3(new Foo, d);
            unique_ptr<Foo, DebugDelete&> up3b(new Foo, d);
            unique_ptr<Foo, DebugDelete> up4(new Foo, DebugDelete());
            unique_ptr<Foo> up5b(std::move(up2));
            unique_ptr<Foo, DebugDelete> up6b(std::move(up3));
    
            unique_ptr<Foo> up7 = std::move(up5b);
            Foo* fp = up7.release();
            assert(up7.get() == nullptr);
            delete fp;
    
            up6b.reset(new Foo());
            up6b.reset(nullptr);
    
            unique_ptr<Fooo> up71(new Fooo(1));
            unique_ptr<Fooo> up72(new Fooo(2));
    
            up71.swap(up72);
    
            std::cout << "up71->val:" << up71->GetBar() << std::endl;
            std::cout << "up72->val:" << (up72.get())->GetBar() << std::endl;
    
            unique_ptr<Foo, D> up8(new Foo(), D());
            D& del = up8.get_deleter();
            del.bar();
        }
    }

    这里写图片描述
    参考:https://www.cnblogs.com/DswCnblog/p/5628195.html

  • 相关阅读:
    分位数(quantiles)、Z-score 与 F-score
    学术研究中的 NLP
    学术研究中的 NLP
    国内外免费电子书(数学、算法、图像、深度学习、机器学习)
    国内外免费电子书(数学、算法、图像、深度学习、机器学习)
    中英文对照 —— 缩略词
    内核编译及模块相关命令使用
    UVA 156 (13.08.04)
    hdu3117之矩阵快速幂
    系统运维技巧(三)——利用dd命令临时增加交换分区
  • 原文地址:https://www.cnblogs.com/Tattoo-Welkin/p/10335288.html
Copyright © 2011-2022 走看看