2015-07-05 94 views
14

STL中有一些以make_前綴開頭的函數,如std::make_pair,std::make_shared,std::make_unique等。爲什麼使用它們而不是簡單地使用構造函數是一種更好的做法?爲什麼使用std :: make_ *而不是構造函數更好?

auto pair2 = std::pair< int, double >(1, 2.0); 
auto pair3 = std::make_pair(1, 2.0); 

std::shared_ptr<int> pointer1 = std::shared_ptr<int>(new int(10)); 
std::shared_ptr<int> pointer2 = std::make_shared<int>(10); 
  • 我剛纔看到的是,這些功能使代碼更短一點,但是是這樣嗎?
  • 還有其他優點嗎?
  • 這些功能是否安全使用?
+1

不太確定新的智能指針,但看看http://stackoverflow.com/questions/9270563/purpose-of-stdmake-pair對。 –

+3

我相信每個人都有明顯的優勢,在不同的現有問題中回答。 'make_pair' [作品沒有作者知道類型](http://stackoverflow.com/questions/9270563)。 'make_shared' [提供異常安全性](http://stackoverflow.com/questions/20895648)。 –

+0

更好,因爲你輸入較少? – texasbruce

回答

15

除了使論證扣除(如其他答案中已經提到的)的好處之外,還有其他一些好處。

std::make_pair<T1, T2>注意不是只需返回std::pair<T1, T2>。如果您使用std::ref傳入值,則返回的對將不會存儲std::reference_wrapper,它將存儲引用。

std::make_shared可以合併分配。 shared_ptr需要一些地方來存放無法直接存儲在shared_ptr中的引用,弱指針列表等內容。這些可以與創建的對象組合在一個稍大的塊中,而不是在兩個單獨的塊中。

std::make_sharedstd::make_unique都確保在拋出異常時不會留下任何對象。如果您調用f(std::shared_ptr<int>(new int), std::shared_ptr<int>(new int))函數,則編譯器可能首先分配兩個對象,然後構造兩個對象shared_ptr<int>。如果第二個分配失敗,並且沒有設置shared_ptr<int>對象以釋放內存銷燬,那麼您有內存泄漏。 std::make_sharedstd::make_unique合併分配int和構造std::shared_ptr<int>在函數調用中,另一個分配int和另一個構造std::shared_ptr<int>在另一個函數調用中。函數調用不能重疊,所以如果第二次分配失敗,已經有一個共享指針將被銷燬,同時撤消第一次分配。

+3

'make_'智能指針還可以通過消除一個不成對的'new',使得'every'new'與'delete''完整性檢查配對。 – Yakk

+0

不確定make_XXX如何保證最後一段的內存釋放。你可以進入更多的細節。 –

+0

@LokiAstari這是更好嗎? – hvd

6

雖然它可能是主觀的,對於該技術的一個主吹捧的好處是:針對接口

寫入代碼,而不是實施方式中

在本質上,功能模板實例進行基於扣除鍵入你傳遞的參數,而類模板實例化不。因此,您不必像直接實例化類時那樣傳遞模板參數。

應該指出,這不是關於「保存幾個字符」,而是關於使你的代碼更一般,並避免綁定到函數調用中的具體類型。

但是,情況並非總是如此,因爲您的示例顯示,仍然有必要將該類型作爲模板參數傳遞的情況。但是,正如Herb Sutter points out,還有其他一些優勢,當談到使用std::make_shared

  1. 你應該清楚和正確性寫第一和std::make_shared實現這兩個的(主觀的,但我同意)

  2. 使用std::make_shared更高效,因爲它一次性分配對象以及shared_ptr對象,從而降低分配開銷並實現更好的緩存對齊。

1

make_unique隱藏你的「原始」指針,通常是一件好事 - 它不太容易出錯。 make_shared可以提高shared_ptr<X>實例的內存分配。通常,當您使用shared_ptr<X>構造函數時,它將分配兩次內存,首先是X,其次是內部數據(例如引用計數器)。 make_shared啓用優化 - 它將創建包含X和引用計數器的單一內部結構,因此它將執行單個內存分配。和之前一樣,它隱藏了原始指針。

+2

但是作爲一個缺點,如果保留weak_ptr ,則shared_ptr 中的所有內存都將保持活動狀態,而不僅僅是ref_count塊。 (但大多數時候並不重要) – minirop

相關問題