智能指針shared_ptr中new和make_ptr兩種方式的區別

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