实现一个shared_ptr和unique_ptr来深入了解C++11 的“最小GC”特性

实现一个简单的智能指针模板shared_ptr和unique_ptr

C++11新特性的智能指针,是C++提供的最小垃圾回收的机制,shared_ptr是一个模板,可以管理指针,并实现自动释放的效果,抹开标准库中shared_ptr对于其它场景的思考, 其核心原理是引用——删除机制,即对于对象的清理在于其引用的个数进行判断,如果没有对象引用这个堆空间,即count=0的时候,就会将其释放。而unique_ptr独占, 无法拷贝和赋值,只能以移动语义传播,下面是一个简化版的Shared_ptrUnique_ptr模板,用于理解shared_ptrunique_ptr的运行原理

  • 支持get(), reset(), 解引用, ->运算符等常用API
  • 没有考虑锁,只是用一个简单的counter字段来记录对Shared_ptr的引用

Shared_ptr

#include <iostream>

using namespace std;

template<class Ty>
class Shared_ptr{
public:

    template<class ...ParametersTy>
    explicit Shared_ptr(ParametersTy&&... args) noexcept :ty(new StoreTy())
    {
        ty->t = new Ty(forward<ParametersTy>(args)...);
    }

    explicit Shared_ptr(Ty* p) noexcept :ty(new StoreTy())
    {
        ty->t = p;
    }

    Shared_ptr(const Shared_ptr<Ty>& p) noexcept : ty(p.ty)
    {
        ty->count++;
    }

    ~Shared_ptr() noexcept
    {
        if(flag){
            ty->count--;
            if(ty->count == 0)
            {
                delete ty->t;
                delete ty;
            }
        }
    }

    size_t use_count() const { return ty->count; }

    Ty* get(){return ty->t;}

    void reset() noexcept
    {
        if(flag)
        {
            flag = false;
            ty->count--;
            if(ty->count == 0)
            {
                delete ty->t;
                delete ty;
            }
        }
    }

    Ty* operator->(){return ty->t;}

private:
    struct StoreTy{
        Ty *t{nullptr};
        int count{1};
    };

    bool flag{true};
    StoreTy* ty;
};

struct Value1{
    void print() { cout << "I am test type Value2\n"; }
};

int main()
{
    Shared_ptr<Value1> p;
    {
        auto p1 = p;
        p1->print();
        p.reset();
        cout<<"Use count "<<p.use_count()<<endl;
    }
    cout<<"Use count "<<p.use_count()<<endl;
}

Unique_ptr

  • 支持unique_ptr特性的模板
#include <iostream>

using namespace std;

template<class Ty>
class Unique_ptr{
public:
    template<class ...ParameterTy>
    explicit Unique_ptr(ParameterTy&& ...args) noexcept : ty(new Ty(std::forward<ParameterTy>(args)...)){}

    Unique_ptr(Unique_ptr&& ptr) noexcept : ty(ptr.ty)
    {
        ptr.ty = nullptr;
    }

    ~Unique_ptr() noexcept {
        if(ty) delete ty;
        ty = nullptr;
    }

    Ty* get(){ return ty; }

    Ty operator*(){ return *ty; }

    Ty* operator->(){ return ty; }

    void reset() noexcept
    {
        if(ty) delete ty;
        ty = nullptr;
    }
private:
    Unique_ptr(const Unique_ptr<Ty>& p) = delete;
    Unique_ptr<Ty> operator=(const Unique_ptr<Ty>& p) = delete;
    Ty* ty;
};

int main(){
    Unique_ptr<int> a(10);
    Unique_ptr<int> c = std::move(a);
    auto e = c;     // 报错,不支持拷贝和赋值
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值