zoukankan      html  css  js  c++  java
  • boost::shared_ptr

    boost::shared_ptr是boost库中用来管理指针的模板,使用它需要#include <boost/shared_ptr.hpp>。本文介绍它的一些基本用法。

    第一,boost::shared_ptr管理的指针所指向的对象必须在堆中,因为该模板会在对象离开作用域后调用delete方法,如果对象位于栈中,程序编译能通过,但在运行中会崩溃。另外改模板提供了swap方法,可以让两个模板指针相互交换所指向的对象。

      1 #include <vector>
      2 #include <set>
      3 #include <iostream>
      4 #include <algorithm>
      5 #include <boost/shared_ptr.hpp>
      6 
      7 //  The application will produce a series of
      8 //  objects of type Foo which later must be
      9 //  accessed both by occurrence (std::vector)
     10 //  and by ordering relationship (std::set).
     11 
     12 struct Foo
     13 {
     14   Foo( int _x ) : x(_x) {}
     15   ~Foo() { std::cout << "Destructing a Foo with x=" << x << "
    "; }
     16   int x;
     17   /* ... */
     18 };
     19 
     20 typedef boost::shared_ptr<Foo> FooPtr;
     21 
     22 typedef struct FooPtrOps
     23 {
     24   bool operator()( const FooPtr & a, const FooPtr & b )
     25   { return a->x > b->x; }
     26   void operator()( const FooPtr & a )
     27   { std::cout << a->x << "
    "; }
     28 } foo_ptr_ops;
     29 
     30 foo_ptr_ops ins_foo_ptr_ops1 = foo_ptr_ops();
     31 FooPtrOps *ins_foo_ptr_ops2 = new FooPtrOps();
     32 FooPtrOps *ins_foo_ptr_ops3 = new foo_ptr_ops;
     33 
     34 
     35 int main()
     36 {
     37   {
     38     std::vector<FooPtr>         foo_vector;
     39     std::set<FooPtr,FooPtrOps>  foo_set; // NOT multiset!
     40 
     41     FooPtr foo_ptr( new Foo( 2 ) );
     42     foo_vector.push_back( foo_ptr );
     43     foo_set.insert( foo_ptr );
     44 
     45     foo_ptr.reset( new Foo( 1 ) );
     46     foo_vector.push_back( foo_ptr );
     47     foo_set.insert( foo_ptr );
     48 
     49     foo_ptr.reset( new Foo( 3 ) );
     50     foo_vector.push_back( foo_ptr );
     51     foo_set.insert( foo_ptr );
     52 
     53     foo_ptr.reset ( new Foo( 2 ) );
     54     foo_vector.push_back( foo_ptr );
     55     foo_set.insert( foo_ptr );
     56 
     57     std::cout << "foo_vector:
    ";
     58     std::for_each( foo_vector.begin(), foo_vector.end(), ins_foo_ptr_ops1 );
     59 
     60     std::cout << "
    foo_set:
    ";
     61     std::for_each( foo_set.begin(), foo_set.end(), *ins_foo_ptr_ops3 );
     62 
     63     FooPtr foo_ptr1( new Foo( 10 ) );
     64     FooPtr foo_ptr2( new Foo( 20 ) );
     65     std::cout << "foo_ptr1: " << foo_ptr1->x << '
    ';
     66     std::cout << "foo_ptr2: " << foo_ptr2->x << '
    ';
     67 
     68     foo_ptr1.swap(foo_ptr2);
     69     std::cout << "After swap:
    ";
     70     std::cout << "foo_ptr1: " << foo_ptr1->x << '
    ';
     71     std::cout << "foo_ptr2: " << foo_ptr2->x << '
    ';
     72 
     73     foo_ptr2.swap(foo_ptr1);
     74     std::cout << "Swap again:
    ";
     75     std::cout << "foo_ptr1: " << foo_ptr1->x << '
    ';
     76     std::cout << "foo_ptr2: " << foo_ptr2->x << '
    ';
     77 
     78     int a = 4;
     79     int b[4] = {6, 7, 0, 5};
     80     int *c = new int();
     81     int *d = new int[3];
     82 
     83     /*
     84      * Because variable a and b are on stack, while boost::shared_ptr will call delete method,
     85      * the following two rows of code will cause error.
     86      */
     87 //    boost::shared_ptr<int> bsa(&a);  // Error: Signal: SIGABRT (Aborted)
     88 //  boost::shared_ptr<int> bsb(b);  // Error: Signal: SIGABRT (Aborted)
     89     boost::shared_ptr<int> bsc(c);
     90     boost::shared_ptr<int> bsd(d);
     91     std::cout << "bsc: " << *bsc << " bsd: " << *bsd << std::endl;
     92 
     93     std::cout << "The variable field finished." << "
    ";
     94   }
     95 
     96   int *c = new int();
     97   int *d = new int[3];
     98   boost::shared_ptr<int> bsc(c);
     99   boost::shared_ptr<int> bsd(d);
    100   std::cout << "bsc: " << *bsc << " bsd: " << *bsd << std::endl;
    101 
    102   std::cout << "
    Program done.
    ";
    103 }

    程序的运行结果:

    foo_vector:
    2
    1
    3
    2
    
    foo_set:
    3
    2
    1
    foo_ptr1: 10
    foo_ptr2: 20
    After swap:
    foo_ptr1: 20
    foo_ptr2: 10
    Swap again:
    foo_ptr1: 10
    foo_ptr2: 20
    bsc: 0 bsd: 0
    The variable field finished.
    Destructing a Foo with x=20
    Destructing a Foo with x=10
    Destructing a Foo with x=2
    Destructing a Foo with x=1
    Destructing a Foo with x=3
    Destructing a Foo with x=2
    bsc: 0 bsd: 7933344
    
    Program done.

     

    第二,boost::shared_ptr支持隐藏类的定义。如下面的代码中,class implementation的定义可以放置于另一个源文件中,在利用boost::shared_ptr管理implementation类型的指针变量时,可以先声明一下类implementation,然后就能定义boost::shared_ptr< implementation >类型的指针变量。

     1 #include <boost/shared_ptr.hpp>
     2 #include <iostream>
     3 #include <algorithm>
     4 
     5 
     6 void print_val(int v)
     7 {
     8     std::cout << v << " ";
     9 }
    10 
    11 class example
    12 {
    13  public:
    14   example();
    15   void do_something();
    16   int val[3];
    17   class implementation;
    18   boost::shared_ptr< implementation > _imp;  // hide implementation details
    19 };
    20 
    21 class example::implementation
    22 {
    23  public:
    24   ~implementation() { std::cout << "destroying implementation
    "; }
    25 };
    26 
    27 example::example() : _imp( new implementation ) {}
    28 
    29 void example::do_something()
    30 {
    31   std::cout << "use_count() is " << _imp.use_count() << "   ";
    32   std::for_each(val, val + 3, print_val);
    33   std::cout << "
    ";
    34 }
    35 
    36 int main()
    37 {
    38   example a;
    39   a.val[0] = 4;
    40   a.val[1] = 5;
    41   a.val[2] = 6;
    42   a.do_something();
    43   example b(a);
    44   b.do_something();
    45   example c;
    46   c = a;
    47   a.do_something();
    48   b.do_something();
    49   c.do_something();
    50   return 0;
    51 }

    程序的运行结果:

    use_count() is 1   4 5 6 
    use_count() is 2   4 5 6 
    destroying implementation
    use_count() is 3   4 5 6 
    use_count() is 3   4 5 6 
    use_count() is 3   4 5 6 
    destroying implementation

    第三,使用boost::shared_ptr提供的reset()方法,可以使boost::shared_ptr管理的指针所指向的对象的引用计数减一。当所指对象的引用计数减至0时,所指对象的析构函数将被调用,所指对象被销毁。

     1 #include <iostream>
     2 #include <string>
     3 #include <boost/shared_ptr.hpp>
     4 
     5 using namespace std;
     6 
     7 
     8 class Book
     9 {
    10  private:
    11   string name_;
    12 
    13  public:
    14   Book(string name) : name_(name)
    15   {
    16     cout << "Creating book " << name_ << " ..." << endl;
    17   }
    18 
    19   ~Book()
    20   {
    21     cout << "Destroying book " << name_ << " ..." << endl;
    22   }
    23 };
    24 
    25 int main()
    26 {
    27   cout << "=====Main Begin=====" << endl;
    28   {
    29     boost::shared_ptr<Book> myBook1(new Book("「1984」"));
    30     cout << "myBook1: " << myBook1.use_count() << endl;
    31     boost::shared_ptr<Book> myBook2(myBook1);
    32     cout << "myBook1: " << myBook1.use_count() << endl;
    33     boost::shared_ptr<Book> myBook3;
    34     myBook3 = myBook1;
    35 
    36     cout << "
    ****************************
    ";
    37     cout << "myBook1: " << myBook1.use_count() << endl;
    38     cout << "myBook2: " << myBook2.use_count() << endl;
    39     cout << "myBook3: " << myBook3.use_count() << endl;
    40 
    41     cout << "
    ****************************
    ";
    42     myBook1.reset();
    43     cout << "myBook1: " << myBook1.use_count() << endl;
    44     cout << "myBook2: " << myBook2.use_count() << endl;
    45     cout << "myBook3: " << myBook3.use_count() << endl;
    46 
    47     cout << "
    ****************************
    ";
    48     myBook3.reset();
    49     cout << "myBook1: " << myBook1.use_count() << endl;
    50     cout << "myBook2: " << myBook2.use_count() << endl;
    51     cout << "myBook3: " << myBook3.use_count() << endl;
    52 
    53     cout << "
    ****************************
    ";
    54     myBook2.reset();
    55     cout << "myBook1: " << myBook1.use_count() << endl;
    56     cout << "myBook2: " << myBook2.use_count() << endl;
    57     cout << "myBook3: " << myBook3.use_count() << endl;
    58 
    59     cout << "After reset ..." << endl;
    60   }
    61   cout << "===== Main End =====" << endl;
    62 
    63   return 0;
    64 }

    程序的运行结果:

    =====Main Begin=====
    Creating book 「1984」 ...
    myBook1: 1
    myBook1: 2
    
    ****************************
    myBook1: 3
    myBook2: 3
    myBook3: 3
    
    ****************************
    myBook1: 0
    myBook2: 2
    myBook3: 2
    
    ****************************
    myBook1: 0
    myBook2: 1
    myBook3: 0
    
    ****************************
    Destroying book 「1984」 ...
    myBook1: 0
    myBook2: 0
    myBook3: 0
    After reset ...
    ===== Main End =====

  • 相关阅读:
    android 请求网络异步载入
    A new Graph Game
    Android 高仿 频道管理----网易、今日头条、腾讯视频 (能够拖动的GridView)附源代码DEMO
    模块管理常规功能自己定义系统的设计与实现(16--模块数据的导出和打印[1])
    ganglia收集hbase的metrics
    ViewPager中View的复用
    PLY格式文件具体解释
    【RefactoringCode】The description of the refactoring book
    2.5星|《故事课2》:几个经典广告案例点评
    2星|叶檀《大破局》:2016年以来的财经时评文集,水平在平均线以下
  • 原文地址:https://www.cnblogs.com/pursuiting/p/10407325.html
Copyright © 2011-2022 走看看