nullptr
空指針是不會指向有效數據的指針,以前用0表示,但是這使得0既可表示指針常量,又可表示整型常量。C++11仍允許使用0來表示空指針,因此表達式nullptr==0爲true,使用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的所有權將被剝奪,好處是防止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類似。