2024年6月6日发(作者:)

POCO C++库学习和分析 -- 内存管理 (二)

3. SharedPtr

SharedPtr是Poco库中基于引用计数实现的另外一种智能指针。同AutoPtr相比,Poco::SharedPtr主

要用于为没有实现引用计数功能的类(换句话说,也就是该类本身不是引用计数对象)提供引用计数服务,

实现动态地址的自动回收。

可以这么说,Poco::AutoPtr是使用继承关系来实现的智能指针,而Poco::SharedPtr是聚合方法实现

的智能指针。

3.1 SharedPtr的类图

首先来看一下SharedPtr的类图:

从类图中可以看到SharedPtr是对引用计数和原生指针封装。其中有成员指针_ptr,指向任意类型的

C;同时还存在一个引用计数对象的指针_pCounter,指向任意一个实现了引用计数的类。当然在Poco库中

提供了ReferenceCount的默认实现,类ReferenceCounter。

比较类ReferenceCounter和AutoPtr中依赖的类RefCountedObject,可以发现其实现相同,本质上就

是一个东西。Poco库中之所以把两者分开,我想是为了明确的表示类与类之间的关系。ReferenceCounter

用于组合,而RefCountedObject用于继承。

SharedPtr在实现模板的时候,还预留了RP参数,这是一个释放策略,用于调整SharedPtr在释放数

组和单个对象之间不同策略的转换。

[cpp] view plaincopy

te >

SharedPtr

3.{

4. // ...

5.}

其中C为对象原生指针,RC为SharedPtr管理的引用计数对象,RP为内存释放策略。

3.2 SharedPtr操作符和值语义

1. Poco::SharedPtr同样支持关系操作符==, !=, <, <=, >, >=;

2. 当Poco::SharedPtr中原生指针为空时,使用解引用操作符“*”或者"->",Poco::SharedPtr会抛出一

个NullPointerException 异常。

3. Poco::SharedPtr同样支持全值语义,包括默认构造函数,拷贝构造函数,赋值函数并且同样可以用

于各类容器(如std::vector 和 std::map)

[cpp] view plaincopy

Ptr& operator = (C* ptr)

2.{

3. return assign(ptr);

4.}

5.

Ptr& assign(C* ptr)

7.{

8. if (get() != ptr)

9. {

10. RC* pTmp = new RC;

11. release();

12. _pCounter = pTmp;

13. _ptr = ptr;

14. }

15. return *this;

16.}

17.

release()