多線程程序常常會遇到在某個線程A建立了一個對象,這個對象須要在線程B使用,ios
在沒有shared_ptr時,由於線程A,B結束時間不肯定,即在A或B線程先釋放這個對象都有可能形成另外一個線程崩潰,數組
因此爲了省時間通常都是任由這個內存泄漏發生.安全
固然也能夠通過複雜的設計,由一個監控線程來統一刪除,多線程
但這樣會增長代碼量和複雜度.這下好了,shared_ptr 能夠方便的解決問題,由於它是引用計數和線程安全的.測試
shared_ptr不用手動去釋放資源,它會智能地在合適的時候去自動釋放。spa
咱們來測試看看效果線程
1 //C++11 shared_ptr 智能指針 的使用,避免內存泄露 2 #include <iostream> 3 #include <memory> 4 using namespace std; 5 6 #define _PRT(T) std::shared_ptr<T> 7 8 //定義 shared_ptr<T> 的智能指針 9 #define _PRTO(T,N,...) std::shared_ptr<T> N(new T(##__VA_ARGS__)) 10 11 //定義 shared_ptr<T> 的數組智能指針 12 #define _PRTA(T,N,n) std::shared_ptr<T> N(new T[n]) 13 14 class A { 15 public: 16 int n; 17 A(int n):n(n) { 18 cout <<n<< " construct A!!!" << endl; 19 } 20 ; 21 ~A() { 22 cout <<n<< " destruct A!!!" << endl; 23 } 24 ; 25 void Out(){ cout << n * 2 << endl; } 26 }; 27 class B : public A { 28 public: 29 B(int n):A(n) { 30 cout <<n<< " construct B!!!" << endl; 31 } 32 ; 33 ~B() { 34 cout <<n<< " destruct B!!!" << endl; 35 } 36 ; 37 _PRT(A) geta(int n) { _PRTO(A,a,n); return a; } 38 39 void chars() { 40 //使用智能指針指向 char[],以自動釋放 41 _PRTA(char,p,1024*1024); 42 strcpy(p.get(), "std::shared_ptr<char*>"); 43 printf(p.get()); 44 } 45 46 }; 47 int main() { 48 B* ptrB0 = new B(1); 49 ptrB0->Out(); 50 51 _PRT(B) ptrB1(new B(2)); 52 ptrB1->Out(); 53 _PRT(A) a = ptrB1->geta(5); 54 a->Out(); 55 //複製了指針,增長引用計數 56 _PRT(B) ptrB2 = ptrB1;57 _PRT(A) b = ptrB2->geta(6); 58 b->Out(); 59 ptrB2->Out(); 60 61 //使用智能指針,會自動釋放 62 for(int i=100;i;i--) 63 ptrB2->chars(); 64 }
測試程序中循環了100次,每次 new 了1Mb的內存, 調試過程當中能夠看到每次循環完內存都沒有增加;設計
而且main執行完後,直接new的 類1 沒有釋放, 而類2自動釋放了,指針
而且 若是有賦值給其餘shared_ptr指針, 指針指向的對象不會釋放,即指針指向的對象不會失效, 除非全部指向此對象的指針都無效了/不用了, 此對象纔會自動釋放.調試