C++11-智能指針和空指針

nullptr

空指針是不會指向有效數據的指針,以前用0表示,但是這使得0既可表示指針常量,又可表示整型常量。C++11仍允許使用0來表示空指針,因此表達式nullptr==0true,使用nullptr表示空指針而不是0提供了更高的類型安全。


智能指針

如果指針ps有一個析構函數,該析構函數將在ps過期時釋放它指向的內存。因此,問題在於它只是一個常規指針,不是有析構函數的類對象。如果它是對象,則可以在對象過期時,讓它的析構函數刪除指向的內存。

 

頭文件memory

std::shared_ptr<string> ps(newstring);

std::shared_ptr<string> ps(newstring("a"));

所有的智能指針類都有一個explicit構造函數

關鍵字:C++中, 一個參數的構造函數(或者除了第一個參數外其餘參數都有默認值的多參構造函數), 承擔了兩個角色。 1是個構造器2是個默認且隱含的類型轉換操作符。在某些情況下(見下面權威的例子),卻違背了我們(程序員)的本意。 這時候就要在這個構造器前面加上explicit修飾, 指定這個構造器只能被明確的調用/使用, 不能作爲類型轉換操作符被隱含的使用。

 

避免兩個指針指向同一個對象,防止多次刪除。可以:

1、定義賦值運算符,使之執行深複製,這樣兩個指針將指向不同的對象。

2、建立所有權概念,對於特定的對象,只能有一個智能指針可以擁有它,這樣只有擁有對象的智能指針的構造函數會刪除該對象。

3、創建智能更高的指針,跟蹤引用特定對象的智能指針數,稱爲引用計數,賦值時,計數加1,指針過期時,計數減1,僅當最後一個指針過期時,才調用delete

 

auto_ptr<string>p1(new string("a"));

auto_ptr<string>p2;

p2 =p1;

在語句3裏面,p2接管string對象的所有權後,p1的所有權將被剝奪,好處是防止p1p2的析構函數試圖刪除同一個對象,但是p1如果再使用的話就很危險。懸掛指針。

 

unique_ptr<string>p1(new string("a"));

unique_ptr<string>p2;

p2 =p1;

這裏的語句3非法,避免了p1不再指向有效數據的問題,因此unique_ptrauto_ptr更安全(編譯階段錯誤比潛在的程序崩潰更安全)。

 

unique_ptr<string>demo(const char *s) {

   unique_ptr<string> temp(newstring(s));

   return temp;

}

unique_ptr<string>ps;

ps =demo("a");

如果unique_ptr是個臨時右值,編譯器允許這樣做,如果源unique_ptr將存在一段時間,編譯器將禁止這樣做。

 

C++11中有一個標準庫函數std::move(),移動構造函數和右值引用。

ps2 =move(ps1);

 

相比於auto_ptrunique_ptr還有另一個優點,它有一個可用於數組的變體

std::unique_ptr<double[]>pda(new double(5));

不過必須使用delete[]來刪除。

 

如果程序要使用多個指向同一個對象的指針,應選擇shared_ptr。能用auto_ptr時,更好選擇unique_ptrBOOST庫提供的scoped_ptrunique_ptr類似。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章