unique_ptr和share_ptr的简单实现

unique_ptr和share_ptr的简单实现

unique_ptr的简单实现

来自
实现智能指针1:unique_ptr
下面列出需要注意的知识点:
1.异常
2.unique_ptr本身功能
3.三五法则和阻止拷贝
4.隐式的类类型转换
5.移动构造、移动赋值及自赋值问题
6.编写模板类。

//reference: https://www.jianshu.com/p/77c2988be336
//第一次错误:在模板类外定义成员函数时,需要声明template<typename T>
//         同时应该是 返回值 类<T>:: 成员函数(参数){}这种格式

template<typename T>
class MyUniquePtr{
public:
    //显式构造
    explicit MyUniquePtr(T* ptr=nullptr):mPtr(ptr){
    }
    ~MyUniquePtr(){
        if(mPtr!=nullptr)
            delete mPtr;
    }
    //移动构造,注意右值引用p会被修改,所以不能用const
    MyUniquePtr(MyUniquePtr&& p) noexcept;
    //移动赋值,同理不能用const
    MyUniquePtr& operator=(MyUniquePtr&& p) noexcept;

    //禁止赋值构造和赋值运算符
    MyUniquePtr(const MyUniquePtr& p)=delete;
    MyUniquePtr& operator=(const MyUniquePtr& p)=delete;
     

    //重载指针的功能
    T* operator->()const noexcept{
        return mPtr;
    }
    T& operator*()const noexcept{
        return *mPtr;
    }


    //使MyUniquePtr能够根据上下文转换为bool类型
    explicit operator bool() const noexcept{
        return mPtr;
    }

    //释放原来的空间,然后指向新的地址空间
    void reset(T* q=nullptr) noexcept{
        if(mPtr!=q){
            if(mPtr!=nullptr)
                delete mPtr;
            mPtr=q;
        }
    }

    //指针置nullptr,原先地址作为返回值返回
    T* release() noexcept{
        T* res=mPtr;
        mPtr=nullptr;
        return res;
    }
    
    //返回内部指针
    T* get()const noexcept{
        return mPtr;
    }

/*
了解一下std::swap的一些特性
1.大概全貌如下:
template<typename T>
void swap(T &a,T &b) noexcept
{
    T temp = std::move(a);
    a = std::move(b);
    b = std::move(temp);
}
2.要求T必须满足MoveAssignable和MoveConstructible
  通俗讲就是有移动构造函数和移动赋值函数
*/
    void swap(MyUniquePtr& p) noexcept{
        using std::swap;
        swap(mPtr,p.mPtr);
    }


private:
    T* mPtr;
};


//移动构造函数(Move Constructors)和移动赋值运算符( Move Assignment Operator)从给定对象窃取资源而不是拷贝资源
template<typename T>
MyUniquePtr<T>::MyUniquePtr(MyUniquePtr&& p) noexcept: mPtr(p.mPtr){
    p.mPtr=nullptr;
}

//这里用swap来避免 在实现赋值运算符是需要检查自我赋值的情况
//https://www.geeksforgeeks.org/copy-swap-idiom-c/
template<typename T>
MyUniquePtr<T>& MyUniquePtr<T>::operator=(MyUniquePtr&& p) noexcept{
    swap(p);
    return *this;
}

shared_ptr的简单实现

来自
实现一个简单的shared_ptr

一般来说,智能指针的实现需要以下步骤:
1.一个模板指针T* ptr,指向实际的对象。
2.一个引用次数(必须new出来的,不然会多个shared_ptr里面会有不同的引用次数而导致多次delete)。
3.重载operator*和operator->,使得能像指针一样使用shared_ptr。
4.重载copy constructor,使其引用次数加一。
5.重载operator=,如果原来的shared_ptr已经有对象,则让其引用次数减一并判断引用是否为零(是否调用delete)。
 然后将新的对象引用次数加一。
6.重载析构函数,使引用次数减一并判断引用是否为零(是否调用delete)。

#ifndef __SHARED_PTR_
#define __SHARED_PTR_

template <typename T>
class shared_ptr {
public:
    shared_ptr(T* p) : count(new int(1)), _ptr(p) {}
    shared_ptr(shared_ptr<T>& other) : count(&(++*other.count)), _ptr(other._ptr) {}
    T* operator->() { return _ptr; }
    T& operator*() { return *_ptr; }

    shared_ptr<T>& operator=(shared_ptr<T>& other)
    {
        //检查自我赋值
        if(this==&other)    return *this;

        ++*other.count;
        if (this->_ptr && 0 == --*this->count)
        {
            delete count;
            delete _ptr;
        }
        this->_ptr = other._ptr;
        this->count = other.count;
        return *this;
    }
    ~shared_ptr()
    {
        if (--*count == 0)
        {
            delete count;
            delete _ptr;
        }
    }
    int getRef() { return *count; }

private:
    int* count;
    T* _ptr;
};

#endif
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值