1.shared_ptr允許有多個指針指向同一個對象,unique_ptr獨占所指向的對象。
2.類似於vector,智能指針也是模板。創建智能指針:
1 shared_ptr<string> p1; //指向string的shared_ptr
2 shared_ptr<list<int>> p2; //指向int的list的shared_ptr
使用make_shared函數分配一個對象並初始化它,make_shared函數返回一個指向此對象的shared_ptr:
1 //指向值為42的int的shared_ptr
2 shared_ptr<int> p3 = make_shared<int>(42); 3
4 //指向一個值為“999”的string
5 shared_ptr<string> p4 = make_shared<string>("999"); 6
7 //指向一個值初始化的int,即值為0
8 shared_ptr<int> p5 = make_shared<int>();
3.我們可以認為每個share_ptr都有一個關聯的計數器,通常稱為引用計數(reference count)。無論何時我們拷貝一個shared_ptr,計數器都會遞增。
例如這些都會使所關聯的計數器遞增:
(1)當用一個shared_ptr初始化另外一個shared_ptr
(2)將它作為參數傳遞給另外一個函數
(3)作為函數的返回值
例如這些操作會使計數器都會遞減:
(1)給share_ptr賦新的值
(2)share_ptr被銷毀
(3)局部的share_ptr離開作用域
以下通過兩個例子來講解計數的規則:
1 shared_ptr<int> p = make_shared<int>(42); 2 shared_ptr<int> q(p); //此對象現在有兩個引用者,計數為2 3 shared_ptr<int> r = make_shared<int>(42); //r現在有一個計數 4 r = q; //r現在指向q所指向的對象了,所以第二個42被銷毀,因為計數為0 5 //而第一個計數為3 6 cout << "p所指對象的引用計數為:" << p.use_count() << endl;
再比如下一個程序:
1 shared_ptr<Foo> factory(T arg) 2 { 3 return make_shared<Foo>(arg); //返回一個shared_ptr<Foo> 4 } 5 void use_factory(T arg) 6 { 7 shared_ptr<Foo> p = factory(arg); //此時p的計數值為1 8 } //由於p是局部變量,出了這個函數,計數值先遞減,然后檢查計數值,發現為0,銷毀p的對象,內存被釋放掉 9 shared_ptr<Foo> use_factory(T arg) 10 { 11 shared_ptr<Foo> p = factory(arg); //此時p的計數值為1 12 return p; //返回了一個智能指針類,計數值加1,為2 13 } //離開了作用域,但是指向的內存不會被釋放,因為還有對象的引用計數不是0
4.當指向的最后一個shared_ptr被銷毀時,是調用析構函數來完成銷毀工作的,析構函數會先遞減它所指向的對象的引用計數,再檢查引用計數值,如果引用計數變為0,那么shared_ptr析構函數就會銷毀對象,並釋放它占用的內存。
附:shared_ptr支持的一些操作:

