本篇要讲的是如何实现一个共享的指针,前面已经提到过了,通过裸指针浅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.
网友评论