nullptr
null 指標是不會指向有效資料的指標,以前用0表示,但是這使得0既可表示指標常量,又可表示整型常量。C++11仍允許使用0來表示null 指標,因此運算式nullptr==0為true,使用nullptr表示null 指標而不是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的所有權將被剝奪,好處是防止p1和p2的解構函式試圖刪除同一個對象,但是p1如果再使用的話就很危險。懸掛指標。
unique_ptr<string>p1(new string("a"));
unique_ptr<string>p2;
p2 =p1;
這裡的語句3非法,避免了p1不再指向有效資料的問題,因此unique_ptr比auto_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_ptr,unique_ptr還有另一個優點,它有一個可用於數組的變體
std::unique_ptr<double[]>pda(new double(5));
不過必須使用delete[]來刪除。
如果程式要使用多個指向同一個對象的指標,應選擇shared_ptr。能用auto_ptr時,更好選擇unique_ptr。BOOST庫提供的scoped_ptr與unique_ptr類似。