c++ primer第五版练习16.28

转自github
链接:https://github.com/HOWEAT/Cpp-Primer/tree/master/ch16/ex16.28

  • sharedpointer.h
#ifndef SHAREDPOINTER_H
#define SHAREDPOINTER_H
#pragma once
#include <functional>

namespace cp5
{

    struct Delete
    {
        template<typename T>
        auto operator() (T* p) const
        {
            delete p;
        }
    };

    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
#endif // SHAREDPOINTER_H

  • u_ptr.h
#ifndef U_PTR_H
#define U_PTR_H

template<typename, typename> class unique_pointer;
template<typename T, typename D> void
                swap(unique_pointer<T, D>& lhs, unique_pointer<T, D>& rhs);

class DebugDelete {
public:
    DebugDelete(ostream &o = cerr):
        os(o){}
    template<typename T> void operator()(T *p) const {
        os<<"delete";
        delete p;
    }
    
/**
 *  @brief  std::unique_ptr like class template.
 */
template <typename T, typename D = DebugDelete>
class unique_pointer
{
    friend void swap<T, D>(unique_pointer<T, D>& lhs, unique_pointer<T, D>& rhs);

public:
    // preventing copy and assignment
    unique_pointer(const unique_pointer&) = delete;
    unique_pointer& operator = (const unique_pointer&) = delete;

    // default constructor and one taking T*
    unique_pointer() = default;
    explicit unique_pointer(T* up): ptr(up) { }

    // move constructor
    unique_pointer(unique_pointer&& up) noexcept
        : ptr(up.ptr)   { up.ptr = nullptr; }

    // move assignment
    unique_pointer& operator =(unique_pointer&& rhs) noexcept;

    // std::nullptr_t assignment
    unique_pointer& operator =(std::nullptr_t n) noexcept;



    // operator overloaded :  *  ->  bool
    T& operator  *() const   { return *ptr; }
    T* operator ->() const   { return & this->operator *(); }
     operator bool() const   { return ptr ? true : false;   }

    // return the underlying pointer
    T* get() const noexcept { return ptr; }

    // swap member using swap friend
    void swap(unique_pointer<T, D> &rhs)  { ::swap(*this, rhs); }

    // free and make it point to nullptr or to p's pointee.
    void reset()     noexcept { deleter(ptr); ptr = nullptr; }
    void reset(T* p) noexcept { deleter(ptr); ptr = p;       }

    // return ptr and make ptr point to nullptr.
    T* release();


    ~unique_pointer()
    {
        deleter(ptr);
    }
private:
    T* ptr = nullptr;
    D  deleter = D();
};


// swap
template<typename T, typename D>
inline void
swap(unique_pointer<T, D>& lhs, unique_pointer<T, D>& rhs)
{
    using std::swap;
    swap(lhs.ptr, rhs.ptr);
    swap(lhs.deleter, rhs.deleter);
}

// move assignment
template<typename T, typename D>
inline unique_pointer<T, D>&
unique_pointer<T, D>::operator =(unique_pointer&& rhs) noexcept
{
    // prevent self-assignment
    if(this->ptr != rhs.ptr)
    {
        deleter(ptr);
        ptr = nullptr;
        ::swap(*this, rhs);
    }
    return *this;
}


// std::nullptr_t assignment
template<typename T, typename D>
inline unique_pointer<T, D>&
unique_pointer<T, D>::operator =(std::nullptr_t n) noexcept
{
    if(n == nullptr)
    {
        deleter(ptr);   ptr = nullptr;
    }
    return *this;
}

 // relinquish contrul by returnning ptr and making ptr point to nullptr.
template<typename T, typename D>
inline T*
unique_pointer<T, D>::release()
{
    T* ret = ptr;
    ptr = nullptr;
    return ret;
}
#endif // U_PTR_H

  • main.cpp
#include <iostream>
#include <string>
#include "sharedpointer.h"

int main()
{
    auto foo = cp5::SharedPointer<int>{ new int(42) };
    auto bar(foo) ;
    std::cout << *foo << std::endl;
    std::cout << foo.use_count() << std::endl;

    auto string_ptr = cp5::SharedPointer<std::string>{ new std::string{ "Yue" } };
    std::cout << *string_ptr << std::endl;
    std::cout << string_ptr->size() << std::endl;

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值