C++实现智能指针

本文探讨了C++11引入的智能指针shared_ptr、unique_ptr和weak_ptr,并着重讲解如何实现一个简单的智能指针,通过引用计数来管理内存。文章从单个指针的自我管理开始,然后介绍如何为类的基类添加引用计数管理,同时提供了一个模板类以简化计数管理。示例展示了类似shared_ptr的使用方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

C++11增加了智能指针:shared_ptr、unique_ptr、weak_ptr

为了加深理解,自己实现智能指针

我们都知道shared_ptr的核心思想通过引用计数来管理内存

先实现单个指针的自我管理,看下面

template <class T>
class Ref
{
public:
    Ref() : m_ptr(NULL)
    {
    }

    Ref(T* p) : m_ptr(p) 
    {
        if (m_ptr)m_ptr->AddRef();
    }

    Ref(const Ref<T>& r) : m_ptr(r.m_ptr) 
    {
        if (m_ptr)m_ptr->AddRef();
    }

    template <typename U>
    Ref(const Ref<U>& r) : m_ptr(r.get())
    {
        if (m_ptr) m_ptr->AddRef();
    }

    ~Ref()
    {
        if (m_ptr) m_ptr->Release();
    }

    T* get() const { return m_ptr; }
    operator T*() const { return m_ptr; }
    T* operator->() const { return m_ptr; }


    T* release() 
    {
        T* retVal = m_ptr;
        m_ptr = NULL;
        return retVal;
    }

    Ref<T>& operator=(T* p) 
    {
        if (p) p->AddRef();
        if (m_ptr) m_ptr ->Release();
        m_ptr = p;
        return *this;
    }

    Ref<T>& operator=(const Ref<T>& r)
    {
        return *this = r.m_ptr;
    }

    template <typename U>
    Ref<T>& operator=(const Ref<U>& r)
    {
        return *this = r.get();
    }

    void swap(T** pp)
    {
        T* p = m_ptr;
        m_ptr = *pp;
        *pp = p;
    }

    void swap(Ref<T>& r)
    {
        swap(&r.m_ptr);
    }

protected:
    T* m_ptr;
};

这部分不难理解

那么,再来需要管理的类的基类

//智能指针基类所有智能指针对象都继承该类
class RefCountedBase
{
public:
    virtual int AddRef()=0;
    virtual int Release()=0;
protected:
    virtual ~RefCountedBase(){}
};

而我们自定义的类需要继承自此类,但是需要实现AddRef和Release,为了方便,再定义一个模板类用于管理计数

template <class T>
class RefCountedObject : public T 
{
public:
    RefCountedObject() : m_count(0) 
    {
    }

    template<typename P>
    explicit RefCountedObject(P p) : T(p), m_count(0) 
    {
    }

    template<typename P1, typename P2>
    RefCountedObject(P1 p1, P2 p2) : T(p1, p2), m_count(0) 
    {
    }

    template<typename P1, typename P2, typename P3>
    RefCountedObject(P1 p1, P2 p2, P3 p3) : T(p1, p2, p3), m_count(0) 
    {
    }

    template<typename P1, typename P2, typename P3, typename P4>
    RefCountedObject(P1 p1, P2 p2, P3 p3, P4 p4)
        : T(p1, p2, p3, p4), m_count(0) 
    {
    }

    template<typename P1, typename P2, typename P3, typename P4, typename P5>
    RefCountedObject(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5)
        : T(p1, p2, p3, p4, p5), m_count(0) 
    {
    }

    virtual int AddRef() 
    {
        return m_count++;
    }

    virtual int Release() 
    {
        int count = --m_count;
        if (!count) 
        {
            delete this;
        }
        return count;
    }

protected:
    virtual ~RefCountedObject() {
    }

    std::atomic_int m_count;
};

而我门在使用的时候,只需类似 shared_ptr的用法:

std::shared_ptr<Test> = std::make_shared<Test>(); 

class Test:public RefCountedBase
{
public:
    void test(){}
};

Ref<Test> test=new RefCountedObject<Test>()
test->test();

参考:https://www.cnblogs.com/zentel/p/3722499.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值