POCO:Foundation 内存储器管理(二) SharedPtr
POCO::Foundation 内存管理(二) SharedPtr
Poco::SharedPtr 实现了针对类的引用计数功能,而这些类不需要自己实现引用计数(AutoPtr的duplicate()和release()函数)。
Poco::SharedPtr有着和Poco::AutoPtr相同的解引用以及相关操作。
警告:赋值指向普通对象的指针到不同的Poco::SharedPtr将导致多个拥有者的产生,进而引起未定义的行为,换句话说,就是crash。
一旦你对一个对象使用Poco::SharedPtr,就不要再使用是想那个对象的指针了。
先来看一个容易理解的例子:有一份对象资源,分别被两个无任何关系的Poco::SharedPtr持有,所以各自的引用计数都是一。而在Poco::SharedPtr内部的析构函数中,会进行这个引用计数值的判断(先减1,再判断是否为0,为0就 delete 持有的资源)。好了,分别析构后,都得到引用计数为0,就产生了两次delete 资源,进而crash。
解决方法就是让其中一个Poco::SharedPtr的引用计数以另一个Poco::SharedPtr引用计数为基础,在其上加1.这样,最终得到0的情况只会发生在一个Poco::SharedPtr身上。
如何建立者两个Poco::SharedPtr的关系呢,那就是拷贝构造函数和=操作符。
可以看到指向资源的_ptr都指向同一份资源,且_pCounter的值来源于另一个_pCounter。 可以看到=操作符的内部产生了一个临时的tmp,通过swap把tmp的_ptr,_pCounter的值交换到this中相应的值中去。除了管理单个对象,Poco::SharedPtr还可以管理对象数组。
其实Poco::SharedPtr模板定义是: 因为第二个和第三个模板参数已经有默认的了,且都有确实实现,所以默认是管理一个对象。当把第三个参数换成内部已经存在的后,从名字也可以看出,它可以管理数组了。总结一下三个模板参数的意义:
class C:要管理的对象类型
class RC:执行引用计数的实现方法
class RP:实现最后析构被管理的对象的方法
谢谢观赏!