智能指针 (3)

上一章:智能指针 (2)
目录

本篇要讲的是如何实现一个共享的指针,前面已经提到过了,通过裸指针浅copy,可以实现指针的共享操作,但是随之而来的问题是谁应该去删除指针所指向的内存。

我们自然而然会想到引用计数,那么,引用计数如何实现呢?关键在于如下几个方面:

(1)在智能指针对象创建时引用计数加1。
(2)在智能指针对象销毁的时候引用计数减1。
(3)引用计数为0时,销毁指针指向的内存。
(4)引用计数必须是所有拥有相同裸指针的对象所共有。

于是,我们可以根据以上思路,写出如下代码:

class SmartIntPtrShared
{
    int* rawPtr_;
    int* counter_;
public:
    SmartIntPtrShared() : rawPtr_(nullptr), counter_(nullptr) {}
    SmartIntPtrShared(int* rawPtr) : rawPtr_(rawPtr), counter_(nullptr)
    {
        if (rawPtr_ != nullptr)
        {
            counter_ = new int(1);
        }
    }
    SmartIntPtrShared(const SmartIntPtrShared& ptr) : rawPtr_(ptr.rawPtr_), counter_(ptr.counter_)
    {
        increaseRef();
    }
    ~SmartIntPtrShared() {release();}
    SmartIntPtrShared& operator=(const SmartIntPtrShared& ptr)
    {
        release();
        rawPtr_ = ptr.rawPtr_;
        counter_ = ptr.counter_;
        increaseRef();
        return *this;
    }

    int* operator->() const {return rawPtr_;}
    int& operator*() const {return *rawPtr_;}
    operator bool () const {return rawPtr_== nullptr;}
    int* get() const {return rawPtr_;}
private:
    void release()
    {
        if (counter_ != nullptr)
        {
            decreaseRef();
            if (*counter_ == 0)
            {
                delete counter_;
                delete rawPtr_;
            }
        }
    }
    void increaseRef()
    {
        if (counter_ != nullptr)
        {
            ++(*counter_);
        }
    }

    void decreaseRef()
    {
        if (counter_ != nullptr)
        {
            ++(*counter_);
        }
    }
};

这里面有几个细节要处理:

(1)counter指针是否为空的判断。
(2)赋值时要把原先的指针先release掉。
(3)counter++时必须为传进来的指针有效。
(4)counter分配内存只存在于SmartIntPtrShared(int* rawPtr)构造时,且rawPtr不会空。

至此,两种的智能指针基本功能已经实现。
C++里面我们可以直接用std::shared_ptr 和 std::unique_ptr.

下一章:智能指针之使用 (3)

目录

你可能感兴趣的:(智能指针 (3))