Poco的智能指针跟标准库的思想是一样的,都是基于引用计数。
主要提供了如下指针
-
AutoPtr
AutoPtr接受的对象必须自己维护引用计数,必须提供release和duplicate两个接口。release用于减少引用,duplicate用于增加引用。它有些类似C++98中的auto_ptr。
默认来说Poco中,继承RefCountedObject基类即可。
注意在Poco2.0版本后,AutoPtr更改为RefPtr,而原来的AutoPtr变为RefPtr的一个别名。
-
SharedPtr
sharedPtr在行为跟c++11中的shared_ptr很类似。在Poco2.0版本之前,Poco是自己实现的SharedPtr,但是2.0后,SharedPtr就是c++11中shared_ptr。只是简单的加了一层封装。
为什么要提供这两个智能指针?
我觉得它最大的好处是提供了通过构造和复制操作可以将普通指针转化成智能指针的能力。
我觉得这个是Poco框架最精髓的地方。正是这种标准库不具备的能力,使得Poco库可以像高级语言一样应用。
举个最简单的例子,标准库和Poco库使用起来,对于智能指针的构造上,前者明显不方便
Class ObjA{} // 定义某个class
std::shared_ptr<ObjA> p1 = new ObjA; // Err!
Poco::SharedPtr<ObjA>p2 = new ObjA;// it works!
对于复杂的调用,可以轻松使用普通指针转智能指针的方式去使用,使堆分配内存可以被方便的托管。
如定义如下函数
void func1(Poco::SharedPtr<ObjA> p) {
// some code here...
}
func1(new ObjA)
如果使用标准库,使用智能指针将会变得麻烦和臃肿。Poco简化了它。其实实现也很简单,不知道为什么标准库不引入这些操作。
对于解引用,Poco同样使用上提供了方便
如下面的例子
Poco::AutoPtr<ObjA> p1(new ObjA);
ObjA * p = p1; // it works!
但是有种情况需要注意的是,如果解引用后的指针再用于初始化另外一个智能指针的话,要注意所有权。如下,
Poco::AutoPtr<ObjA> p1(new ObjA);
ObjA * p = p1; // it works!
Poco::AutoPtr<ObjA> p2(pA); // BAD! p1和p2析构会引发crash
Poco::AutoPtr<ObjA> p2(pA, true); // 这样可以,p1和p2共享
Poco::AutoPtr<ObjA> p3;
p3 = p; // p1和p3都独享指针,会有异常
p3.assign(p, true); //OK
这种特性是如何实现的呢
主要是两个地方
-
提供唯一指针入参的无explicit修饰的构造函数;以及重载=,使它接受指针入参。
2.提供类型转换并且无explicit修饰
就这样,指针的行为就和高级语言里的类一样好使啦。