shared_ptr的实现

同文章unique_ptr,值得一看的模板例程

/***************************************************************************
*  @file       shared_pointer.hpp
*  @author     Yue Wang
*  @date       04  Feb 2014
*                  Jul 2015
*                  Oct 2015 
*  @remark     This code is for the exercises from C++ Primer 5th Edition
*  @note
***************************************************************************/

#pragma once
#include <functional>
#include "delete.hpp"

namespace cp5
{
    template<typename T>
    class SharedPointer;

    template<typename T>
    auto swap(SharedPointer<T>& lhs, SharedPointer<T>& rhs)
    {
        using std::swap;
        swap(lhs.ptr, rhs.ptr);
        swap(lhs.ref_count, rhs.ref_count);
        swap(lhs.deleter, rhs.deleter);
    }

    template<typename T>
    class SharedPointer
    {
    public:
        //
        //  Default Ctor
        //
        SharedPointer()
            : ptr{ nullptr }, ref_count{ new std::size_t(1) }, deleter{ cp5::Delete{} }
        { }
        //
        //  Ctor that takes raw pointer
        //
        explicit SharedPointer(T* raw_ptr)
            : ptr{ raw_ptr }, ref_count{ new std::size_t(1) }, deleter{ cp5::Delete{} }
        { }
        //
        //  Copy Ctor
        //
        SharedPointer(SharedPointer const& other)
            : ptr{ other.ptr }, ref_count{ other.ref_count }, deleter{ other.deleter }
        {
            ++*ref_count;
        }
        //
        //  Move Ctor
        //
        SharedPointer(SharedPointer && other) noexcept
            : ptr{ other.ptr }, ref_count{ other.ref_count }, deleter{ std::move(other.deleter) }
        {
            other.ptr = nullptr;
            other.ref_count = nullptr;
        }
        //
        //  Copy assignment
        //
        SharedPointer& operator=(SharedPointer const& rhs)
        {
            //increment first to ensure safty for self-assignment
            ++*rhs.ref_count;
            decrement_and_destroy();
            ptr = rhs.ptr, ref_count = rhs.ref_count, deleter = rhs.deleter;
            return *this;
        }
        //
        //  Move assignment
        //
        SharedPointer& operator=(SharedPointer && rhs) noexcept
        {
            cp5::swap(*this, rhs);
            rhs.decrement_and_destroy();
            return *this;
        }
        //
        //  Conversion operator
        //
        operator bool() const
        {
            return ptr ? true : false;
        }
        //
        //  Dereference
        //
        T& operator* () const
        {
            return *ptr;
        }
        //
        //  Arrow
        //
        T* operator->() const
        {
            return &*ptr;
        }
        //
        //  Use count
        //
        auto use_count() const
        {
            return *ref_count;
        }
        //
        //  Get underlying pointer
        //
        auto get() const
        {
            return ptr;
        }
        //
        //  Check if the unique user
        //
        auto unique() const
        {
            return 1 == *refCount;
        }
        //
        //  Swap
        //
        auto swap(SharedPointer& rhs)
        {
            ::swap(*this, rhs);
        }
        //
        // Free the object pointed to, if unique
        //
        auto reset()
        {
            decrement_and_destroy();
        }
        //
        // Reset with the new raw pointer
        //
        auto reset(T* pointer)
        {
            if (ptr != pointer)
            {
                decrement_and_destroy();
                ptr = pointer;
                ref_count = new std::size_t(1);
            }
        }
        //
        //  Reset with raw pointer and deleter
        //
        auto reset(T *pointer, const std::function<void(T*)>& d)
        {
            reset(pointer);
            deleter = d;
        }
        //
        //  Dtor
        //
        ~SharedPointer()
        {
            decrement_and_destroy();
        }
    private:
        T* ptr;
        std::size_t* ref_count;
        std::function<void(T*)> deleter;

        auto decrement_and_destroy()
        {
            if (ptr && 0 == --*ref_count)
                delete ref_count, 
                deleter(ptr);
            else if (!ptr)
                delete ref_count;
            ref_count = nullptr;
            ptr = nullptr;
        }
    };
}//namespace
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值