首頁 >後端開發 >C++ >`make_shared` 與建構子初始化的 `shared_ptr`:效能和例外安全性有何不同?

`make_shared` 與建構子初始化的 `shared_ptr`:效能和例外安全性有何不同?

Barbara Streisand
Barbara Streisand原創
2024-12-11 00:40:16407瀏覽

`make_shared` vs. Constructor-Initialized `shared_ptr`: What's the Performance and Exception Safety Difference?

make_shared 和建構子初始化的shared_ptr之間的區別

場景

考慮以下程式碼片段:

std::shared_ptr<Object> p1 = std::make_shared<Object>("foo");
std::shared_ptr<Object> p2(new Object("foo"));

理解原因make_shared比使用shared_ptr更有效構造函數直接需要一步步分析所涉及的操作。

操作比較

make_shared

  • 執行單一堆分配以建立連續的記憶體區塊對於控制區塊(元資料)和託管區塊

建構函式初始化的shared_ptr

  • 呼叫new Obj("foo"),為託管物件建立堆疊分配。
  • 然後,呼叫shared_ptr建構函數,該構造函數為控制項執行另一個堆分配block.

記憶體分配

make_shared 僅分配記憶體一次,而建構函數初始化的shared_ptr 分配記憶體兩次。這使得 make_shared 更有效率。

異常安全

在 C 17 中,修改了函數參數的求值順序,消除了建構函式初始化的 shared_ptr 方法的異常安全問題。但是,讓我們考慮以下範例:

void F(const std::shared_ptr<Lhs> &lhs, const std::shared_ptr<Rhs> &rhs) { /* ... */ }

F(std::shared_ptr<Lhs>(new Lhs("foo")), std::shared_ptr<Rhs>(new Rhs("bar")));

如果在 Rhs 建構子期間引發異常,則為 Lhs 分配的記憶體將會遺失,因為它沒有立即傳遞給 shared_ptr 建構子。 make_shared 透過消除這個中間步驟來避免這個問題。

make_shared 的缺點

但是,make_shared 有一個缺點:由於它在單一堆疊中分配控制區塊和託管對象,因此兩者都不能獨立釋放。這意味著弱指標可以使控制塊無限期地保持活動狀態,從而可能防止控制塊和託管物件被釋放。

以上是`make_shared` 與建構子初始化的 `shared_ptr`:效能和例外安全性有何不同?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn