boost shared_ptr的使用方法

1. boost::shared_ptr的用法

下面用一个简单的例子说明shared_ptr的用法:

#include <stdio.h>

#include <boost/shared_ptr.hpp>

 

class A {

public:

    void print() {

        printf("classA print!\n");

    }

};

 

int main(int argc, char **argv) {

   boost::shared_ptr<A> a1(new A());

    a1->print();

}

 

shared_ptr不用手动去释放资源,它会智能地在合适的时候去自动释放。如上面的例子,a1指向的对象将会在程序结束的时候自动释放(程序结束时所有申请的资源都会被释放,这只是为了说明其作用)。再来看下面的例子:

//同上

int main(int argc, char **argv) {

    boost::shared_ptr<A> a1(new A());

    a1->print();

    printf("a1 reference count: %d\n",a1.use_count());

    boost::shared_ptr<A> 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());

}

 

程序输出结果:

classA print!

a1reference count: 1

a1reference count: 2

a2reference 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

template<classD> shared_ptr(std::nullptr_t p, D d);

template<class D, classA> shared_ptr(std::nullptr_t p, D d, A a);

 

上面几个函数可以初始化一个空的shared_ptr指针,其中,第三和第四个函数中的参数的意思是:d表示一个删除器(deleter),它会在释放资源的时候被调用,delete p会变成d(p)a表示一个构造器,被用作分配空间。这两个接口允许调用者自己提供构造器和删除器,来自定义自己的构造和释放行为。


(2) 根据变量构造指针 

template<classY> explicit shared_ptr(Y * p);

template<classY, class D> shared_ptr(Y * p, D d);

template<class Y,class D, class A> shared_ptr(Y * p, D d, A a);


这几个构造函数是通过一个Y类型的指针类型p来初始化shared_ptr指针,初始化后,指针会指针p所指的对象。其中,参数da的意义和上面相同。


(3) 拷贝构造函数

shared_ptr拥有常见的拷贝构造,移动构造函数,用法和普通构造函数一样,这里不做详述。还有一个比较特殊的构造函数:

template<class Y> shared_ptr(shared_ptr<Y> 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<object>o (new object); // use_count == 1

  shared_ptr<data> d(o, &o->data_); // use_count == 2

 

  o.reset (); // use_count== 1

 

  // When d goes out ofscope, object is deleted.

}

 

void g ()

{

  typedefstd::vector<object> objects;

 

 shared_ptr<objects> os (new objects); // use_count == 1

  os->push_back (object());

  os->push_back (object());

 

  shared_ptr<object>o1 (os, &os->at (0)); // use_count == 2

  shared_ptr<object>o2 (os, &os->at (1)); // use_count == 3

 

  os.reset (); //use_count == 2

 

  // When o1 goes out ofscope, use_count becomes 1.

  // When o2 goes out ofscope, objects is deleted.

}


3. 使用 boost::shared_ptr的注意事项

(1)  不要把一个原生指针给多个shared_ptr管理 

int*ptr = new int;

boost::shared_ptr<int>p1(ptr);

boost::shared_ptr<int>p2(ptr);


这样做会导致ptr会被释放两次。在实际应用中,保证除了第一个shared_ptr使用ptr定义之外,后面的都采用p1来操作,就不会出现此类问题。


(2)  不要在函数实参里创建 shared_ptr

function(shared_ptr<int>(newint), g());  //有缺陷

    //可能的过程是先new int,然后调g()g()发生异常,shared_ptr<int>没有创建,int内存泄露

    //推荐写法

    shared_ptr<int> p(new int());

    f(p, g());

 

 (3)  shared_ptr作为被保护的对象的成员时,小心因循环引用造成无法释放资源。

简单的例子:

classparent;

classchildren;

typedefboost::shared_ptr<parent> parent_ptr;

typedefboost::shared_ptr<children> children_ptr;

 

classparent {

public:

    children_ptr children;

};

 

classchildren {public:

    parent_ptr parent;

};

voidtest()

{

    boost::shared_ptr<parent> father( newparent);

    boost::shared_ptr<children> son(newchildren);

    father->children = son;//user_count() == 2

    son->parent = father;//user_count() == 2

}

 

在这个例子中,出现了循环引用计数,赋值后use_count()变为2,出函数后变为1,资源无法被释放。boost的解决方法是采用 weak_ptr来保存。

 

classparent {public:

   boost::weak_ptr<children> children;

};

 

classchildren {public:

     boost::weak_ptr<father> parent;

};

 

因为boost不会影响weak_ptr不会影响引用计数,不会造成循环引用计数。

  (4)  不要把this指针给shared_ptr

this指针赋给shared_ptr会出现this指针被释放两次的危险,如下面的代码,会在t释放时析构一次,shared_ptr释放时析构一次。

 

classtest {

  public:

    boost::shared_ptr<test> pget() {

      returnboost::shared_ptr<test>(this);

  }       

};

 

testt;

boost::shared_ptr<test>pt = t.pget();

 

boost库提供的解决方法是:使用enable_shared_from_this来实现。

 

classtest : public boost::enable_shared_from_this<test> {

  public:

    boost::shared_ptr<test> pget() {

      return shared_from_this();

  }       

};

 

testt;

boost::shared_ptr<test>pt = t.pget();

 

4.std::tr1::shared_ptrboost::shared_ptr

在新版本的C++标准中引用shared_ptr智能指针,名空间是std::tr1::shared_ptr。它和boost::shared_ptr的用法相同,在gcc4.3.x及以上的版本加选项 -std=gnu++0x即可使用。



文章来源

http://blog.csdn.net/yusiguyuan/article/details/20076061

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
boost::shared_ptr是一个智能指针类,用于管理动态分配的对象。它提供了自动内存管理和资源释放的功能,可以避免内存泄漏和悬空指针的问题。\[1\] boost::shared_ptr的用法包括以下几个方面: 1. 创建shared_ptr对象:可以通过构造函数将指针传递给shared_ptr对象,也可以使用make_shared函数创建shared_ptr对象。 2. 使用shared_ptr对象:可以通过shared_ptr对象的get函数获取原始指针,通过*操作符访问指针指向的对象,通过->操作符访问对象的成员。 3. 共享所有权:多个shared_ptr对象可以共享同一个指针,当最后一个shared_ptr对象销毁时,会自动释放指针指向的对象。 4. 自定义删除器:可以通过构造函数或reset函数的第二个参数指定一个删除器,用于在shared_ptr对象销毁时执行特定的清理操作。 5. 避免循环引用:当存在循环引用时,可以使用weak_ptr来打破循环引用,避免内存泄漏。 boost::shared_ptr的实现机制是通过引用计数来管理对象的生命周期。每个shared_ptr对象都有一个引用计数,当有新的shared_ptr对象指向同一个指针时,引用计数加1;当shared_ptr对象销毁时,引用计数减1。当引用计数为0时,表示没有任何shared_ptr对象指向该指针,此时会自动释放指针指向的对象。 使用boost::shared_ptr需要注意以下几点: 1. 避免在多线程环境下同时访问同一个shared_ptr对象,需要进行适当的线程同步。 2. 不要将原始指针和shared_ptr混合使用,避免出现悬空指针或重复释放的问题。 3. 避免循环引用,使用weak_ptr来打破循环引用。 4. 注意使用shared_ptr的成员函数和操作符,如reset、swap、==、!=等。 关于boost::shared_ptr的更多详细信息,可以参考boost官方文档\[3\]。同时,还可以了解std::tr1::shared_ptrboost::shared_ptr之间的差异和使用方式\[4\]。 #### 引用[.reference_title] - *1* *2* *3* [有关智能指针(shared_ptr)的讨论](https://blog.csdn.net/weixin_30236595/article/details/96687717)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值