1. boost::shared_ptr的用法
下面用一个简单的例子说明shared_ptr的用法:
#include#include class A { public: void print() { printf("class A print!\n"); } }; int main(int argc, char **argv) { boost::shared_ptr a1(new A()); a1->print(); }
shared_ptr不用手动去释放资源,它会智能地在合适的时候去自动释放。如上面的例子,a1指向的对象将会在程序结束的时候自动释放(程序结束时所有申请的资源都会被释放,这只是为了说明其作用)。再来看下面的例子:
//同上 int main(int argc, char **argv) { boost::shared_ptr a1(new A()); a1->print(); printf("a1 reference count: %d\n", a1.use_count()); boost::shared_ptr a2 = a1; printf("a1 reference count: %d\n", a1.use_count()); printf("a2 reference count: %d\n", a2.use_count()); a1.reset(); printf("a2 reference count: %d\n", a2.use_count()); }
程序输出结果:
class A print! a1 reference count: 1 a1 reference count: 2 a2 reference count: 2 a2 reference count: 1
上面调用了两上shared_ptr的成员方法,user_count()的作用是获得当前对象被引用的次数,reset()的作用是释放指针对对象的引用,将指针设为空。
2. boost::shared_ptr的实现机制
boost::shared_ptr的实现机制其实比较简单,就是对指针引用的对象进行引用计数,当有一个新的boost::shared_ptr指针指向一个对象时,就把该对象的引用计数加1,减少一个boost::shared_ptr指针指向一个对象时,就把对该对象的引用计数减1。当一个对象的引用计数变为0时,就会自动调用其析构函数或者free掉相应的空间。
boost::shared_ptr的常用成员函数:
(1) 构造一个空的指针
shared_ptr(); // never throws shared_ptr(std::nullptr_t); // never throws templateshared_ptr(std::nullptr_t p, D d); template shared_ptr(std::nullptr_t p, D d, A a);
上面几个函数可以初始化一个空的shared_ptr指针,其中,第三和第四个函数中的参数的意思是:d表示一个删除器(deleter),它会在释放资源的时候被调用,delete p会变成d(p)。a表示一个构造器,被用作分配空间。这两个接口允许调用者自己提供构造器和删除器,来自定义自己的构造和释放行为。
(2) 根据变量构造指针
templateexplicit shared_ptr(Y * p); template shared_ptr(Y * p, D d); template shared_ptr(Y * p, D d, A a);
这几个构造函数是通过一个Y类型的指针类型p来初始化shared_ptr指针,初始化后,指针会指针p所指的对象。其中,参数d和a的意义和上面相同。
(3) 拷贝构造函数
shared_ptr拥有常见的拷贝构造,移动构造函数,用法和普通构造函数一样,这里不做详述。还有一个比较特殊的构造函数:
templateshared_ptr(shared_ptr const & r, element_type * p); // never throws
这个函数的在boost的帮助文档中解释为:constructs a shared_ptr that shares ownership with r and stores p(构造一个shared_ptr对象存储p并且与r共享所有权),这个构造函数被称为aliasing constructor(不知道如何翻译,aliasing有重叠的意思)。r是将要共享所有权的指针,p是实际指向的对象,构造的指针调用get()或者operator->将返回p,而不是r。为了更好的理解这个函数,我们考虑shared_ptr指针对象由两个部分构成,一个是它的所有权(可以与其他指针共享的),另一个是它实际存储的对象。在普通应用中,这两部分是相同的。在由上述函数构造的shared_ptr中,两个部分是不同的。当一个指针的引用计数为0时,如果它还与其他指针共享所有权,那么它实际存储的对象不会被删除,直到共享的引用计数为0。下面的例子会更直观一些。
struct data {...};
struct object
{
data data_;
};
void f ()
{
shared_ptr