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 << "\n"; }
 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 << "\n"; }
 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:\n";
 58     std::for_each( foo_vector.begin(), foo_vector.end(), ins_foo_ptr_ops1 );
 59 
 60     std::cout << "\nfoo_set:\n";
 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 << '\n';
 66     std::cout << "foo_ptr2: " << foo_ptr2->x << '\n';
 67 
 68     foo_ptr1.swap(foo_ptr2);
 69     std::cout << "After swap:\n";
 70     std::cout << "foo_ptr1: " << foo_ptr1->x << '\n';
 71     std::cout << "foo_ptr2: " << foo_ptr2->x << '\n';
 72 
 73     foo_ptr2.swap(foo_ptr1);
 74     std::cout << "Swap again:\n";
 75     std::cout << "foo_ptr1: " << foo_ptr1->x << '\n';
 76     std::cout << "foo_ptr2: " << foo_ptr2->x << '\n';
 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." << "\n";
 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 << "\nProgram done.\n";
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\n"; }
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 << "\n";
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 << "\n****************************\n";
37     cout << "myBook1: " << myBook1.use_count() << endl;
38     cout << "myBook2: " << myBook2.use_count() << endl;
39     cout << "myBook3: " << myBook3.use_count() << endl;
40 
41     cout << "\n****************************\n";
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 << "\n****************************\n";
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 << "\n****************************\n";
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 =====

posted @ 2019-02-20 16:12  洗盏更酌  Views(3773)  Comments(0Edit  收藏  举报