ITPub博客

首页 > 数据库 > 数据库开发技术 > boost shared_ptr, weak_ptr

boost shared_ptr, weak_ptr

原创 数据库开发技术 作者:liiinuuux 时间:2016-09-26 13:05:33 0 删除 编辑
头文件

点击(此处)折叠或打开

  1. #include <boost/smart_ptr.hpp>
  2. #include <boost/make_shared.hpp>

简单使用

点击(此处)折叠或打开

  1. int main()
  2. {
  3.     boost::shared_ptr<string> sp(new string("aaa")); // 构造函数接受一个new出来的指针
  4.     cout << "ref count " << sp.use_count() << endl; // 引用计数
  5.     cout << "exclude " << sp.unique() << endl; // 指针是否被自己独占
  6.     {
  7.         boost::shared_ptr<string> sp2 = sp; // 赋值的时候,引用计数会增加

  8.         // sp和sp2都能看到引用计数,unique()返回false
  9.         cout << "ref count " << sp.use_count() << endl;
  10.         cout << "exclude " << sp.unique() << endl;
  11.         cout << "ref count " << sp2.use_count() << endl;
  12.         cout << "exclude " << sp2.unique() << endl;

  13.         // 可以通过任意指向这个字符串对象的shared_ptr操作字符串对象
  14.         // 支持 ->* 操作符来模拟普通指针
  15.         sp2->append("xxx");
  16.     }
  17.     // sp2的作用于至于大括号,大括号结束后,引用计数减小1,unique()有返回ture了
  18.     cout << "ref count " << sp.use_count() << endl;
  19.     cout << "exclude " << sp.unique() << endl;

  20.     cout << *sp << endl;

  21.     // 最后sp会析构,最后一个析构的shared_ptr会自动delete 指向的对象。
  22.     return 0;
  23. }

可以用make_shared来去掉显示new,这样new和delete都被隐藏了。

点击(此处)折叠或打开

  1. boost::shared_ptr<string> sp = boost::make_shared<string>("aaa");

不仅仅直接赋值,任何拷贝shared_ptr的行为都会增加引用计数

点击(此处)折叠或打开

  1. boost::shared_ptr<string> func(boost::shared_ptr<string> s)
  2. {
  3.     cout << "in func ref count " << s.use_count() << endl; // 参数拷贝后引用计数变成2
  4.     return s;
  5. }

  6. int main()
  7. {
  8.     boost::shared_ptr<string> sp = boost::make_shared<string>("aaa");
  9.     cout << "ref count " << sp.use_count() << endl; // 刚开始引用计数是1
  10.     boost::shared_ptr<string> sp2 = func(sp); // 退出函数后,参数被析构了,引用计数变成1,但是返回值又让引用计数升到2
  11.     cout << "ref count " << sp.use_count() << endl;
  12.     sp2.reset(); // sp2释放对象
  13.     cout << "ref count " << sp.use_count() << endl; // 引用计数变回1
  14.     return 0;
  15. }

  16. [root@server2 test]# ./a
  17. ref count 1
  18. in func ref count 2
  19. ref count 2
  20. ref count 1

另一种隐含增加引用计数的情况

点击(此处)折叠或打开

  1. int main()
  2. {
  3.     vector<boost::shared_ptr<int> > v;
  4.     {
  5.         int i;
  6.         for(i=0; i<10; i++)
  7.         {
  8.             v.push_back(boost::make_shared<int>(i));
  9.         }
  10.     }
  11.     
  12.     //由于stl容器的元素是拷贝进去的,因此shared_ptr维护的对象也不会被销毁
  13.     cout << v[5].use_count() << endl;
  14.     return 0;
  15. }

weak_ptr可以用来监控shared_ptr,但是不会影响引用计数

点击(此处)折叠或打开

  1. boost::shared_ptr<int> sp1 = boost::make_shared<int>(100);
  2.     cout << "ref count " << sp1.use_count() << endl;
  3.     boost::weak_ptr<int> wp1(sp1);
  4.     boost::weak_ptr<int> wp2 = sp1;
  5.     boost::weak_ptr<int> wp3 = wp2;
  6.     // 虽然定义了3个weak_ptr,但是引用计数没有改变,从weak_ptr里可以取出shared_ptr的引用计数
  7.     cout << "ref count " << sp1.use_count() << endl;
  8.     cout << "ref count " << wp1.use_count() << endl;
  9.     cout << "ref count " << wp2.use_count() << endl;
  10.     cout << "ref count " << wp3.use_count() << endl;
  11.     cout << endl;

  12.     //创建新的shared_ptr
  13.     boost::shared_ptr<int> sp2 = sp1;
  14.     boost::shared_ptr<int> sp3 = wp1.lock(); // 可以从weak_ptr生成shared_ptr
  15.     cout << "ref count " << sp1.use_count() << endl;
  16.     cout << "ref count " << wp1.use_count() << endl;
  17.     cout << "ref count " << wp2.use_count() << endl;
  18.     cout << "ref count " << wp3.use_count() << endl;
  19.     cout << endl;
  20.     sp1.reset();
  21.     sp2.reset();
  22.     sp3.reset();

  23.     // shared_ptr销毁资源后,从weak_ptr可以查看状态wp1.expired()
  24.     cout << "ref count " << wp1.use_count() << endl;
  25.     cout << "expired " << wp1.expired() << endl;


  26. [root@server2 test]# ./a
  27. ref count 1
  28. ref count 1
  29. ref count 1
  30. ref count 1
  31. ref count 1

  32. ref count 3
  33. ref count 3
  34. ref count 3
  35. ref count 3

  36. ref count 0
  37. expired 1

析构

点击(此处)折叠或打开

  1. int main()
  2. {
  3.     int* i = new int(100);
  4.     {
  5.         boost::shared_ptr<int> sp1(i);
  6.     }
  7.     // 在大括号里把i交给shared_ptr管理了,大括号结束后,由于引用计数变成0,shared_ptr在析构的同时执行了delete i
  8.     // 因此大括号结束后,指针i已经失效了,手工调用delete会发生core dump
  9.     delete i;
  10.     return 0;
  11. }

自定义删除函数后,shared_ptr会把delete i 换成我们指定的del(i)

点击(此处)折叠或打开

  1. void del(int* i)
  2. {
  3.     cout << "deleter " << *i << endl;
  4. }

  5. int main()
  6. {
  7.     int* i = new int(100);
  8.     {
  9.         boost::shared_ptr<int> sp1(i, del);
  10.     }

  11.     // 由于在del函数里只是打印了i,并没有delete i,因此指针i扔是有效的。
  12.     delete i;
  13.     return 0;
  14. }

暴露this指针

点击(此处)折叠或打开

  1. 以下代码,A将this封装成shared_ptr提供给其它类
  2. class printer;
  3. class A: public enable_shared_from_this<A>
  4. {
  5. public:
  6.     A(int i, printer* p): _i(i), _p(p){};
  7.     int get() const { return _i; };
  8.     void print();
  9. private:
  10.     int _i;
  11.     printer* _p;
  12.     shared_ptr<A> get_this() { return shared_from_this();};
  13. };

  14. class printer
  15. {
  16. public:
  17.     void print(shared_ptr<A> a) { cout << a->get() << endl; }
  18. };

  19. void A::print() {_p->print(get_this()); }

  20. int main()
  21. {
  22.     printer p;
  23.     shared_ptr<A> a = make_shared<A>(100, &p);
  24.     a->print();
  25.     return 0;
  26. }

















来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/26239116/viewspace-2125591/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2012-11-12

  • 博文量
    94
  • 访问量
    309770