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 =====