C++智能指針實現(shared_ptr, non-intrusive reference count)

題計

根據上編智能指針好文中counted_ptr.h,實現智指針。

智能指針實現的方式

在這裏插入圖片描述
在這裏插入圖片描述 (下面代碼按照該方式實現)
在這裏插入圖片描述

代碼

#include <iostream>

class Data {
public:
    Data(int data) : data(data){}
    ~Data() {
        std::cout << "~Data(): " << data << std::endl;
    }
    int data;
};

template <class T>
class SmartPtr {
public:
    // 明確/顯示 構造,不支持 SmartPtr<Data> s = new T();
    explicit SmartPtr(T* obj = nullptr) : counter(nullptr)
    {
        if (obj != nullptr) {
            counter = new Counter(obj); // 創建引用計數對象,智能指針對象(指向相同對象)共有
        }
    }
    // 智能指針對象析構時,引用計數對象--
    ~SmartPtr()
    {
        Release();
    }
    // 拷貝構造函數: 引用計數對象++
    SmartPtr(const SmartPtr& smartPtr) {
        //Release(); 本身一開始就是空的,不用對引用計數對象進行--
        Acquire(smartPtr.counter);
    }
    // 賦值構造函數: 本對象應用計數先--,然後將應用計數對象指針指向賦值對象,並計數對象++
    SmartPtr& operator=(const SmartPtr& smartPtr) {
        if (this != &smartPtr) {
            Release();
            Acquire(smartPtr.counter);
        }

        return *this;
    }
    // 指針取值操作符
    T& operator*() const throw()
    {
        return *counter->obj;
    }

    T* operator->() const throw()
    {
        return counter->obj;
    }

    // 取裸指針操作
    T* Get() const throw()
    {
        return counter == nullptr ? nullptr : counter->obj;
    }
    // 求引用計數對象中的引用計數
    int UseCount()
    {
        if (counter == nullptr) {
            return 0;
        } else {
            return counter->refCount;
        }
    }
private:
    // 引用計數對象,將對象和引用計數綁定在一起,不同的智能指針對象指向同一個引用計數對象
    struct Counter {
        Counter(T* obj = nullptr, int refCount = 1) : obj(obj), refCount(refCount){}
        int refCount;
        T* obj;
    };

    // 引用計數--
    void Release()
    {
        if (counter) {
            if (--counter->refCount == 0) {
                delete counter->obj; // 釋放真正的對象
                delete counter; // 釋放應用計數對象
                counter = nullptr; // 賦空,防止dangling指針,懸掛指針
            }
        }
    }

    // 應用計數++
    void Acquire(Counter* c) {
        counter = c;
        if (counter) {
            counter->refCount++;
        }
    }

    Counter* counter;
};

int main()
{
    SmartPtr<Data> smartPtr1(new Data(1));
    SmartPtr<Data> smartPtr2(new Data(2));
    //SmartPtr<Data> smartPtr2(smartPtr1);
    std::cout << "smartPtr1.UseCount: " << smartPtr1.UseCount() << std::endl;
    std::cout << "smartPtr2.UseCount: " << smartPtr2.UseCount() << std::endl;
    smartPtr1 = smartPtr2;
    std::cout << "smartPtr1.UseCount: " << smartPtr1.UseCount() << std::endl;
    std::cout << "smartPtr2.UseCount: " << smartPtr2.UseCount() << std::endl;

    return 0;
}

運行結果:

smartPtr1.UseCount: 1
smartPtr2.UseCount: 1
~Data(): 1
smartPtr1.UseCount: 2
smartPtr2.UseCount: 2
~Data(): 2

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章