C++ make_shared 用法小結(jié)
以下是C++中std::make_shared
的用法詳解及核心要點(diǎn),結(jié)合實(shí)踐場景和代碼示例說明:
?? ?一、基本用法與語法?
std::make_shared
是C++11引入的模板函數(shù),用于創(chuàng)建并管理std::shared_ptr
智能指針,語法如下:
#include <memory> std::shared_ptr<T> ptr = std::make_shared<T>(構(gòu)造參數(shù)...);
?示例?:
class MyClass { public: MyClass(int v) : data(v) {} private: int data; }; int main() { auto obj = std::make_shared<MyClass>(42); // 創(chuàng)建對象并初始化 return 0; }
- ?作用?:替代
new T(...)
,自動管理內(nèi)存生命周期,避免手動delete
。
? ?二、核心優(yōu)勢?
1. ?性能優(yōu)化(一次內(nèi)存分配)??
?傳統(tǒng)方式?(std::shared_ptr<T>(new T)
):
先分配對象內(nèi)存,再分配控制塊(引用計(jì)數(shù)等),共 ?2次內(nèi)存分配。
?**make_shared
?:
將對象和控制塊合并為單次內(nèi)存分配**,減少內(nèi)存碎片,提升性能(約30%速度提升)
std::shared_ptr<int> p1(new int(10)); // 2次分配(低效) auto p2 = std::make_shared<int>(10); // 1次分配(高效)
2. ?異常安全?
若構(gòu)造函數(shù)拋出異常,make_shared
能保證已分配的內(nèi)存被自動釋放,而傳統(tǒng)方式可能泄漏:
// 傳統(tǒng)方式:若computePriority()拋出異常,new int的內(nèi)存泄漏 process(std::shared_ptr<int>(new int), computePriority()); // make_shared:異常安全 process(std::make_shared<int>(), computePriority());
由于make_shared
是原子操作,避免了中間狀態(tài)導(dǎo)致的內(nèi)存泄漏。
3. ?代碼簡潔性?
- 避免顯式
new
,減少代碼冗余。
?? ?三、實(shí)際應(yīng)用場景?
1. ?共享對象所有權(quán)?
多個(gè)shared_ptr
共享同一對象,引用計(jì)數(shù)歸零時(shí)自動釋放:
auto obj = std::make_shared<MyClass>(); auto obj2 = obj; // 引用計(jì)數(shù)+1 std::cout << obj.use_count(); // 輸出2
對象在obj
和obj2
均析構(gòu)后釋放。
2. ?解決循環(huán)引用?
使用weak_ptr
打破循環(huán)依賴:
class B; class A { public: std::weak_ptr<B> b_ptr; // 弱引用 }; class B { public: std::shared_ptr<A> a_ptr; }; int main() { auto a = std::make_shared<A>(); auto b = std::make_shared<B>(); a->b_ptr = b; // 弱引用,不增加計(jì)數(shù) b->a_ptr = a; // 強(qiáng)引用 return 0; // 正確釋放資源 }
若使用shared_ptr
互相持有會導(dǎo)致內(nèi)存泄漏。
3. ?高效創(chuàng)建數(shù)組(C++20+)??
// C++20支持make_shared創(chuàng)建數(shù)組 auto arr = std::make_shared<int[]>(5); arr[0] = 42;
C++11/14需手動構(gòu)造:std::shared_ptr<int[]>(new int[5])
。
?? ?四、使用限制與注意事項(xiàng)?
?不支持自定義刪除器?make_shared
無法指定刪除器,需直接使用shared_ptr
構(gòu)造函數(shù)
auto ptr = std::shared_ptr<FILE>(fopen("file.txt", "r"), [](FILE* f){ fclose(f); });
?延遲內(nèi)存釋放問題?
對象內(nèi)存和控制塊合并分配后,若存在weak_ptr
,則對象內(nèi)存需等到所有weak_ptr
析構(gòu)才釋放(強(qiáng)引用計(jì)數(shù)為0時(shí)僅析構(gòu)對象,內(nèi)存塊可能未釋放)。
?適用場景?:對內(nèi)存敏感的系統(tǒng)需謹(jǐn)慎使用。
?私有構(gòu)造函數(shù)限制?
若類構(gòu)造函數(shù)為private
或protected
,需通過友元或靜態(tài)工廠函數(shù)間接調(diào)用make_shared
。
??? ?五、最佳實(shí)踐建議?
- ?**優(yōu)先使用
make_shared
**?:除非需要自定義刪除器或處理私有構(gòu)造,否則默認(rèn)選用。 - ?避免循環(huán)引用?:成員指針優(yōu)先用
weak_ptr
,尤其父子對象互相引用時(shí)。 - ?性能敏感場景?:高頻創(chuàng)建對象時(shí)(如實(shí)時(shí)系統(tǒng)),
make_shared
的性能優(yōu)勢更顯著。
?? ?總結(jié)?
std::make_shared
是現(xiàn)代C++內(nèi)存管理的核心工具:
- ?高效?:單次內(nèi)存分配提升性能;
- ?安全?:異常安全避免泄漏;
- ?簡潔?:代碼更清晰易維護(hù)。
在共享所有權(quán)、資源自動釋放及高性能場景中不可或缺,但需注意其內(nèi)存釋放機(jī)制和構(gòu)造限制。
到此這篇關(guān)于C++ make_shared 用法小結(jié)的文章就介紹到這了,更多相關(guān)C++ make_shared內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
剖析C++編程當(dāng)中指針作為函數(shù)參數(shù)的用法
這篇文章主要介紹了剖析C++編程當(dāng)中指針作為函數(shù)參數(shù)的用法,是C++入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下2015-09-09C++中priority_queue與仿函數(shù)實(shí)現(xiàn)方法
這篇文章主要給大家介紹了關(guān)于C++中priority_queue與仿函數(shù)實(shí)現(xiàn)的相關(guān)資料,優(yōu)先級隊(duì)列是一種容器適配器,其底層通常采用vector容器,并通過堆算法來維護(hù)元素的順序,文中通過代碼介紹的非常詳細(xì)《》需要的朋友可以參考下2024-10-10C語言實(shí)現(xiàn)單位車輛調(diào)度管理
這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)單位車輛調(diào)度管理,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03C語言數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)字符串分割的實(shí)例
這篇文章主要介紹了C語言數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)字符串分割的實(shí)例的相關(guān)資料,希望通過本文能幫助到大家實(shí)現(xiàn)這樣的功能,需要的朋友可以參考下2017-10-10利用Matlab實(shí)現(xiàn)時(shí)域分析功能的示例詳解
利用MATLAB可以方便地進(jìn)行控制系統(tǒng)的時(shí)域分析。這篇文章主要通過簡單的示例為大家介紹了Matlab進(jìn)行時(shí)域分析的具體操作,需要的可以參考一下2023-02-02