C++11_std::make_shared的優(yōu)點

視頻教程:https://www.bilibili.com/video/av86947941

shared_ptr維護引用計數(shù)需要的信息

  • 強引用, 用來記錄當前有多少個存活的 shared_ptrs 正持有該對象. 共享的對象會在最后一個強引用離開的時候銷毀( 也可能釋放).
  • 弱引用, 用來記錄當前有多少個正在觀察該對象的 weak_ptrs. 當最后一個弱引用離開的時候, 共享的內(nèi)部信息控制塊會被銷毀和釋放 (共享的對象也會被釋放, 如果還沒有釋放的話).

使用原始的new函數(shù)創(chuàng)建shared_ptr

  • 首先是原始的new分配了原始對象, 然后將這個對象傳遞給 shared_ptr (即使用 shared_ptr 的構(gòu)造函數(shù)) , shared_ptr 對象只能單獨的分配控制塊。
  • 控制塊包含被指向?qū)ο蟮囊糜嫈?shù)以及其他,也就是說,控制塊的內(nèi)存是在std::shared_ptr的構(gòu)造函數(shù)中分配的。

使用make_shared創(chuàng)建shared_ptr

  • 如果選擇使用 make_shared 的話, 內(nèi)存分配的動作, 可以一次性完成,因為std::make_shared申請一個單獨的內(nèi)存塊來同時存放指向的對象和控制塊,這減少了內(nèi)存分配的次數(shù), 而內(nèi)存分配是代價很高的操作。
  • 同時,使用std::make_shared消除了一些控制塊需要記錄的信息,減少了程序的總內(nèi)存占用。

make_shared實現(xiàn)異常安全

  • 在shared_ptr的使用過程中,不能在函數(shù)實參中創(chuàng)建shared_ptr,如下:
//Define
void F(const std::shared_ptr<Lhs>& lhs, const std::shared_ptr<Rhs>& rhs) 
{
  ;
}
//Call
F(std::shared_ptr<Lhs>(new Lhs("foo")),std::shared_ptr<Rhs>(new Rhs("bar")));

C++ 是不保證參數(shù)求值順序, 以及內(nèi)部表達式的求值順序的, 所以可能的執(zhí)行順序如下:

new Lhs(“foo”))
new Rhs(“bar”))
std::shared_ptr<Lhs>
std::shared_ptr<Rhs>

如果在第2步的時候,發(fā)生了異常,第一步申請的 Lhs 對象內(nèi)存就泄露了,
產(chǎn)生這個問題的核心在于, shared_ptr 沒有立即獲得裸指針,所以就有可能產(chǎn)生內(nèi)存泄漏。當然,這個問題是可以這樣解決:

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

但,最推薦的做法是

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

因為,申請原始對象和將原始對象裸指針賦值給shared_ptr是在同一個執(zhí)行序列里,失敗的話一起失敗,成功就一起成功,這樣就能保住創(chuàng)建的原始對象裸指針能安全的存放到std::shared_ptr中

使用make_shared的缺點

  • 創(chuàng)建的對象如果沒有公有的構(gòu)造函數(shù)時,make_shared無法使用。
  • 使用make_shared內(nèi)存可能無法及時回收,對內(nèi)存要求要的場景需要注意。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 讓我們從對齊std::make_unique 和 std::make_shared這兩塊開始。std::make_...
    starmier閱讀 1,532評論 0 5
  • C++裸指針的內(nèi)存問題有:1、空懸指針/野指針2、重復(fù)釋放3、內(nèi)存泄漏4、不配對的申請與釋放 使用智能指針可以有效...
    WalkeR_ZG閱讀 3,291評論 0 5
  • make_shared的使用: 盡量使用make_shared初始化 C++11 中引入了智能指針, 同時還有一個...
    宋大壯閱讀 193,419評論 11 47
  • C#、Java、python和go等語言中都有垃圾自動回收機制,在對象失去引用的時候自動回收,而且基本上沒有指針的...
    StormZhu閱讀 3,889評論 1 15
  • 今天發(fā)生的事,很好的給我上了一課。通過此事,我要反省自己: 1. 做事粗枝大葉,魯莽不細心。慢和安全是一切的基礎(chǔ)。...
    寵愛自己_715b閱讀 194評論 0 0

友情鏈接更多精彩內(nèi)容