C++ make_shared 用法小結(jié)
以下是C++中std::make_shared的用法詳解及核心要點,結(jié)合實踐場景和代碼示例說明:
?? ?一、基本用法與語法?
std::make_shared是C++11引入的模板函數(shù),用于創(chuàng)建并管理std::shared_ptr智能指針,語法如下:
#include <memory> std::shared_ptr<T> ptr = std::make_shared<T>(構造參數(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)存,再分配控制塊(引用計數(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. ?異常安全?
若構造函數(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)導致的內(nèi)存泄漏。
3. ?代碼簡潔性?
- 避免顯式
new,減少代碼冗余。
?? ?三、實際應用場景?
1. ?共享對象所有權?
多個shared_ptr共享同一對象,引用計數(shù)歸零時自動釋放:
auto obj = std::make_shared<MyClass>(); auto obj2 = obj; // 引用計數(shù)+1 std::cout << obj.use_count(); // 輸出2
對象在obj和obj2均析構后釋放。
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; // 弱引用,不增加計數(shù)
b->a_ptr = a; // 強引用
return 0; // 正確釋放資源
}若使用shared_ptr互相持有會導致內(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需手動構造:std::shared_ptr<int[]>(new int[5])。
?? ?四、使用限制與注意事項?
?不支持自定義刪除器?make_shared無法指定刪除器,需直接使用shared_ptr構造函數(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析構才釋放(強引用計數(shù)為0時僅析構對象,內(nèi)存塊可能未釋放)。
?適用場景?:對內(nèi)存敏感的系統(tǒng)需謹慎使用。
?私有構造函數(shù)限制?
若類構造函數(shù)為private或protected,需通過友元或靜態(tài)工廠函數(shù)間接調(diào)用make_shared。
??? ?五、最佳實踐建議?
- ?**優(yōu)先使用
make_shared**?:除非需要自定義刪除器或處理私有構造,否則默認選用。 - ?避免循環(huán)引用?:成員指針優(yōu)先用
weak_ptr,尤其父子對象互相引用時。 - ?性能敏感場景?:高頻創(chuàng)建對象時(如實時系統(tǒng)),
make_shared的性能優(yōu)勢更顯著。
?? ?總結(jié)?
std::make_shared是現(xiàn)代C++內(nèi)存管理的核心工具:
- ?高效?:單次內(nèi)存分配提升性能;
- ?安全?:異常安全避免泄漏;
- ?簡潔?:代碼更清晰易維護。
在共享所有權、資源自動釋放及高性能場景中不可或缺,但需注意其內(nèi)存釋放機制和構造限制。
到此這篇關于C++ make_shared 用法小結(jié)的文章就介紹到這了,更多相關C++ make_shared內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
剖析C++編程當中指針作為函數(shù)參數(shù)的用法
這篇文章主要介紹了剖析C++編程當中指針作為函數(shù)參數(shù)的用法,是C++入門學習中的基礎知識,需要的朋友可以參考下2015-09-09
C++中priority_queue與仿函數(shù)實現(xiàn)方法
這篇文章主要給大家介紹了關于C++中priority_queue與仿函數(shù)實現(xiàn)的相關資料,優(yōu)先級隊列是一種容器適配器,其底層通常采用vector容器,并通過堆算法來維護元素的順序,文中通過代碼介紹的非常詳細《》需要的朋友可以參考下2024-10-10
C語言數(shù)據(jù)結(jié)構實現(xiàn)字符串分割的實例
這篇文章主要介紹了C語言數(shù)據(jù)結(jié)構實現(xiàn)字符串分割的實例的相關資料,希望通過本文能幫助到大家實現(xiàn)這樣的功能,需要的朋友可以參考下2017-10-10

