shared_ptr是c++11中的智能指針,其可以自動的釋放指針,避免了new之後忘記delete的問題。
shared_ptr 對象在內部指向兩個內存位置:
1、指向對象的指針。
2、用於控制引用計數數據的指針。
計數數據指針的作用:
1、當新的 shared_ptr 對象與指針關聯時,使用use_count(),其指針關聯的引用計數增加1。
2、當任何 shared_ptr 對象超出作用域時,則在其析構函數中,它將關聯指針的引用計數減1。如果引用計數變爲0,則表示沒有其他 shared_ptr 對象與此內存關聯,在這種情況下,它使用delete函數刪除該內存。
創建 shared_ptr 對象
- 使用原始指針創建 shared_ptr 對象
- 帶有參數的 shared_ptr 構造函數是 explicit 類型的,所以不能像這樣
std::shared_ptr<int> p1 = new int(),正確的創建方式如下:
std::shared_ptr<int> ptr2(new int());
此方法在堆上創建了兩塊內存:1:存儲int
。2:控制塊上用於引用計數的內存,管理附加此內存的 shared_ptr 對象的計數,最初計數將爲1。
使用make_ptr創建空的 shared_ptr 對象
std::shared_ptr<int> ptr = std::make_shared<int>();
std::make_shared 一次性爲int
對象和用於引用計數的數據都分配了內存,而new
操作符只是爲int
分配了內存。
分離關聯的指針
1.要使 shared_ptr 對象取消與相關指針的關聯,可以使用reset()
函數:
ptr.reset();
2.可以直接設爲nullptr
ptr = nullptr;
給shared_ptr添加自定義刪除器
當 shared_ptr 對象調用其析構函數,它將引用計數減1,如果引用計數的新值爲0,則刪除關聯的原始指針。析構函數中刪除內部原始指針,默認調用的是delete()
函數。 當shared_ptr指向數組時,該函數針對數組類型創建的指針是不起作用的,需要自己來自定義一個刪除器來delete[].
//刪除器
void deleter(Sample * x)
{
std::cout << "delete\n";
delete[] x;
}
//第二個參數傳遞自定義刪除器指針
std::shared_ptr<Sample> p(new Sample[2], deleter);
new和make_ptr的區別
- new是分配兩次內存,make_ptr分配一次
- 在C++ 11中因爲make_shared有std::move語義,在加上O2優化選項的時候,make_shared會比new快上將近1倍