c++11学习笔记(7)- 智能指针的简单实现

原创
2022-11-23
4657
0

上一篇文章中简单介绍了只能指针的简单使用,文章链接如下:
c++11学习笔记(6)- 智能指针
本片文章简单介绍一下智能指针的实现

1. auto_ptr的简单实现

代码如下:

template<typename T>
class MAutoPtr
{
public:
    MAutoPtr(T* p) : m_pData(p){}
    ~MAutoPtr() {
        delete m_pData;
    }

    MAutoPtr(MAutoPtr& ptr) {
        m_pData = ptr.m_pData;
        ptr.m_pData = nullptr;
    }

    MAutoPtr& operator= (MAutoPtr& ptr) {
        m_pData = ptr.m_pData;
        ptr.m_pData = nullptr;
        return *this;
    }

    T& operator* (void) {
        return *m_pData;
    }

    T* operator-> (void) {
        return m_pData;
    }
private:
    T *m_pData = nullptr;
};

测试代码如下:

MAutoPtr<int> ptr(new int(10));
std::cout << *ptr << std::endl;
MAutoPtr<int> ptr2 = ptr;
std::cout << *ptr2 << std::endl;

运行结果:
10
10

auto_ptr的实现比较简单,在构造函数的时候为指针赋值,并且将赋值过来的指针置nullptr就可以了。


2. unique_ptr的简单实现

代码如下:

template<typename T>
class MUniquePtr
{
public:
    MUniquePtr(T* p) : m_pData(p) {
        
    }
    ~MUniquePtr() {
        delete m_pData;
    }
    MUniquePtr(MUniquePtr&& ptr) {
        m_pData = ptr.m_pData;
        ptr.m_pData = nullptr;
    }

    MUniquePtr& operator= (MUniquePtr&& ptr) {
        m_pData = ptr.m_pData;
        ptr.m_pData = nullptr;
    }

    T& operator* (void) {
        return *m_pData;
    }

    T* operator-> (void) {
        return m_pData;
    }

    MUniquePtr(const MUniquePtr& ptr) = delete;
    MUniquePtr& operator= (const MUniquePtr& ptr) = delete;
private:
    T* m_pData = nullptr;
};

测试代码如下:

MUniquePtr<int> uptr(new int(20));
std::cout << *uptr << std::endl;
MUniquePtr<int> uptr2 = std::move(uptr);
std::cout << *uptr2 << std::endl;

运行结果:
20
20

说明:大体上跟 auto_ptr 差不多,不同的是屏蔽了默认构造函数和默认赋值操作函数,使用移动构造函数和移动赋值操作函数替代。

3. shared_ptr的简单实现

代码如下:

template<typename>
class SharedPtr;

template<typename T>
class SharedData
{
public:
    SharedData(T* p):m_pData(p), m_Size(1){}
    ~SharedData() {
        delete m_pData;
    }

    friend class SharedPtr<T>;
private:
    T* m_pData = nullptr;
    int m_Size = 0;
};

template<typename T>
class SharedPtr
{
public:
    SharedPtr(T* p){
        m_pData = new SharedData<T>(p);
    }
    ~SharedPtr() {
        if (m_pData->m_Size > 1)
        {
            m_pData->m_Size--;
            return;
        }
        else
            delete m_pData;
    }

    SharedPtr(const SharedPtr& pData) {
        m_pData = pData.m_pData;
        m_pData->m_Size = pData.m_pData->m_Size;
        m_pData->m_Size++;
    }

    SharedPtr& operator= (const SharedPtr& pData) {
        if (m_pData == pData->m_pData)
            return;
            
        if (--m_pData ->size == 0)
            delete m_pData;
            
        m_pData = pData.m_pData;
        m_pData->m_Size++;
        return *this;
    }

    T& operator* () {
        return *(m_pData->m_pData);
    }
    T* operator-> () {
        return m_pData->m_pData;
    }

    // 获取当前的引用计数
    int count_number(void) {
        return m_pData->m_Size;
    }
private:
    SharedData<T>* m_pData = nullptr;
};

测试代码如下:

SharedPtr<int> sharedPtr(new int(30));
std::cout << *sharedPtr << std::endl;
std::cout << sharedPtr.count_number() << std::endl;
SharedPtr<int> sharedPtr2 = sharedPtr;
*sharedPtr = 50;
std::cout << *sharedPtr2 << ", " << *sharedPtr << std::endl;
std::cout << sharedPtr.count_number() << std::endl;

运行结果:
30
1
50, 50
2

说明: 实用模板类 SharedData 存放共享数据和指针的引用计数,在释放智能指针 SharedPtr 时,引用计数减1,当引用计数为0的时候再释放内存。
不会飞的纸飞机
扫一扫二维码,了解我的更多动态。

下一篇文章:c++11学习笔记(8)- 可变参数宏、函数、模板