標籤:
C++智能指標主要是在普通指標的基礎上封裝了一層,使得使用者對指標的使用更加方便和放心,在使用的過程中不用擔心指標因為釋放問題而導致的異常。在C++11中,智能指標主要有三種:shared_ptr<T> ptr, unique_ptr<T> ptr, weak_ptr<T> ptr; shared_ptr<T> ptr的初始化可以通過以下幾種方式: 1)shared_ptr<T> ptr = make_shared<T>(args); //args的參數形式和T的建構函式一致。 2)shared_ptr<T> ptr(q); //q可以是一個智能指標或者普通指標(轉換成T*的也行,比如&v),還能是一塊新分配的記憶體。 3)shared_ptr<T> ptr = q; //q可以是智能指標或者一般指標,但不能是一塊新分配的記憶體。 4)shared_ptr<T> ptr(u); //u是一個unique_ptr,此時u被被置位null,ptr指向u之前所指向的對象。 5)shared_ptr<T> ptr(q, d); //和方法2)類似,但是會用新的刪除函數d取代delete 但是智能指標最好不要和不同指標混著用。 其它一些操作,如: 1)ptr = q; //ptr指向q指向的對象,q必須是智能指標。ptr和q的模版類型不一定要完全一樣,只要可以從q的模版類型轉向ptr的模版類型即可。此時ptr原來指向的對象引用計數減1,q指向的對象引用計數加1。 2)ptr.unique();//返回ptr所指向的對象引用數是否為1。 3)p.use_count(); //後者返回ptr所指向對象引用數。 與一般指標相比,shared_ptr主要可以用來防止記憶體流失和懸掛指標: 1)記憶體流失是指動態分配的記憶體被遺忘釋放了,導致這塊記憶體一直不能被回收,一般較難檢測出來,除非泄漏的記憶體非常多導致程式記憶體不夠用了。如果使用普通指標,就可能導致這個問題,比如:T *p = new T(); T *p= new T(); 此時p第一次指向的記憶體塊就泄漏了。還有一種情況也可能導致記憶體流失: T* f(T arg) { T *ptr = new T(arg); ...; } //此時如果ptr不主動釋放他所指向的記憶體,等到出了函數f的範疇,ptr指向的空間就會出現記憶體流失。 而智能指標本身也是一個對象,它有自己的解構函式,當智能指標失效時,它會自動調用解構函式,刪除自身,並將所指向對象的引用值減1,引用值為0就會刪除所指向對象。 2)懸掛指標是指向一塊記憶體空間,這塊記憶體空間之前儲存一個對象,但是後來因為delete其他指標時被刪除了,此時該指標就是懸掛指標。而使用智能指標,當刪除一個智能指標時,首先將指向對象的引用值減1,如果此時引用值為0才會刪除該對象。 ptr.reset(); //是指ptr不再指向之前所指向的對象。 ptr.reset(q); //是指ptr不在指向之前所指向的對象,轉而指向q所對應或指向的空間。 ptr.reset(q, d); //同上,只是用d替換了delete函數,在必要時,會調用d刪除之前所指向的對象。 使用智能指標需要注意以下幾點: 1)不要使用不同指標初始化或者reset多個智能指標。 2)不要delete從get()返回的指標。 3)不要使用get()返回的指標去初始化其它智能指標。 4)如果使用了get(),需要注意,智能指標將所指空間內容刪除時,會使得get()返回的對象指標成為懸掛指標。 unique_ptr<T> ptr是一個可以保證只有一個unique_ptr指標指向一個對象,它的初始化方法只要有以下幾種: 1)unique_ptr<T> ptr(q); //q可以是一塊新分配的記憶體或者普通指標。 2)unique_ptr<T, D> ptr = ...; 和shared_ptr不同,unique_ptr需要指定自訂刪除函數類型的指標。 ptr.release(); //此時ptr不再指向之前所指向的對象,並返回之前所指向對象的指標,調用這個函數的時候,最好(務必)將函數的返回值存到某個指標,不然就記憶體流失了。 shared_ptr和unique_ptr幾個相同的函數: 1)p; //用p作為條件判斷指標p是否為空白。 2)*p; //取p所指向的對象引用。 3) p->mem; //訪問p所指對象的成員變數。 4)p.get(); //返回所指對象的普通指標。 weak_ptr顧名思義,弱指標,將一個shared_ptr綁定到weak_ptr不會影響shared_ptr所指向對象的引用數。他主要有以下幾個方法: 1)weak_ptr<T> w = sp; 以及 w = sp; //將一個share_ptr綁定到weak_ptr。 2)weak_ptr<T> w(sp); //同上。 3)reset(); //釋放綁定的sp; 4)use_count(); //所指對象的引用數。 5)expired(); //判斷use_count()是否為0。0返回true,否則返回false。 6)lock(); //返回所綁定的一個shared_ptr,如果已經不存在,則返回一個空的shared_ptr。
C++ 智能指標