第一范文网 - 专业文章范例文档资料分享平台

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

来源:用户分享 时间:2025/12/24 23:46:57 本文由loading 分享 下载这篇文档手机版
说明:文章内容仅供预览,部分内容可能不全,需要完整文档或者需要复制内容,请下载word后使用。下载word有问题请添加微信号:xxxxxxx或QQ:xxxxxx 处理(尽可能给您提供完整文档),感谢您的支持与谅解。

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

1. template > 2. class 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

1. SharedPtr& operator = (C* ptr) 2. {

3. return assign(ptr); 4. } 5.

6. SharedPtr& 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.

18. void release()

19. {

20. poco_assert_dbg (_pCounter); 21. int i = _pCounter->release(); 22. if (i == 0) 23. {

24. RP::release(_ptr); 25. _ptr = 0; 26.

27. delete _pCounter; 28. _pCounter = 0; 29. } 30. }

注意,在SharedPtr赋值操作符\中的操作,对于原生指针_ptr的操作策略是交换,而引用计数对象_pCounter的策略是先new一个,再交换。

4. 可以用SharedPtr::isNull()和SharedPtr::operator ! () 去检查内部的原生指针是否为空。

3.3 SharedPtr和Cast类型转换

同普通指针类似,Poco::SharedPtr支持cast操作符。这在 template SharedPtr cast() const中实现,其定义如下:

[cpp] view plaincopy

1. template

2. SharedPtr cast() const

3. /// Casts the SharedPtr via a dynamic cast to the given type. 4. /// Returns an SharedPtr containing NULL if the cast fails. 5. /// Example: (assume class Sub: public Super) 6. /// SharedPtr super(new Sub()); 7. /// SharedPtr sub = super.cast(); 8. /// poco_assert (sub.get()); 9. {

10. Other* pOther = dynamic_cast(_ptr); 11. if (pOther)

12. return SharedPtr(_pCounter, pOther); 13. return SharedPtr(); 14. }

Poco::SharedPtr中类型转换总是安全的,在其内部实现时,使用了dynamic_cast ,所以一个不合法的转换,会导致原生指针为空。

Poco::SharedPtr中赋值操作符的兼容性通过构造函数和赋值操作符共同完成。

[cpp] view plaincopy

1. template

2. SharedPtr& operator = (const SharedPtr& ptr) 3. {

4. return assign(ptr); 5. }

6.

7. template

8. SharedPtr& assign(const SharedPtr& ptr) 9. {

10. if (ptr.get() != _ptr) 11. {

12. SharedPtr tmp(ptr); 13. swap(tmp); 14. }

15. return *this; 16. } 17.

18. template

19. SharedPtr(const SharedPtr& ptr): _pCounter(ptr._pCounter), _ptr(const_cast

er*>(ptr.get())) 20. {

21. _pCounter->duplicate(); 22. }

下面是关于操作符的一个例子:

[cpp] view plaincopy

1. #include \ 2. class A 3. { 4. public:

5. virtual ~A() 6. {} 7. };

8. class B: public A 9. { 10. };

11. class C: public A 12. { 13. };

14. int main(int argc, char** argv) 15. {

16. Poco::SharedPtr pA; 17. Poco::SharedPtr pB(new B);

18. pA = pB; // okay, pB is a subclass of pA 19. pA = new B;

20. // pB = pA; // will not compile 21. pB = pA.cast(); // okay 22. Poco::SharedPtr pC(new C);

23. pB = pC.cast(); // pB is null 24. return 0; 25. }

POCO C++库学习和分析-- 内存管理(二).doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印
本文链接:https://www.diyifanwen.net/c0m8811z56157ejb0pt6s_1.html(转载请注明文章来源)
Copyright © 2012-2023 第一范文网 版权所有 免责声明 | 联系我们
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ:xxxxxx 邮箱:xxxxxx@qq.com
渝ICP备2023013149号
Top