C 语言

关注公众号 jb51net

关闭
首页 > 软件编程 > C 语言 > C++ make_shared

C++ make_shared 用法小结

作者:Ring__Rain

std::make_shared是C++11引入的模板函数,用于创建并管理std::shared_ptr智能指针,具有一定的参考价值,感兴趣的可以了解一下

以下是C++中std::make_shared的用法详解及核心要点,结合实践场景和代码示例说明:

📌 ​一、基本用法与语法​

std::make_shared是C++11引入的模板函数,用于创建并管理std::shared_ptr智能指针,语法如下:

#include <memory>
std::shared_ptr<T> ptr = std::make_shared<T>(构造参数...);

示例​:

class MyClass {
public:
    MyClass(int v) : data(v) {}
private:
    int data;
};
 
int main() {
    auto obj = std::make_shared<MyClass>(42); // 创建对象并初始化
    return 0;
}

⚡ ​二、核心优势​

1. ​性能优化(一次内存分配)​​

传统方式​(std::shared_ptr<T>(new T)):
先分配对象内存,再分配控制块(引用计数等),共 ​2次内存分配

​**make_shared​:
将对象和控制块合并为
单次内存分配**,减少内存碎片,提升性能(约30%速度提升)

std::shared_ptr<int> p1(new int(10));   // 2次分配(低效)
auto p2 = std::make_shared<int>(10);    // 1次分配(高效)

2. ​异常安全​

若构造函数抛出异常,make_shared能保证已分配的内存被自动释放,而传统方式可能泄漏:

// 传统方式:若computePriority()抛出异常,new int的内存泄漏
process(std::shared_ptr<int>(new int), computePriority());
 
// make_shared:异常安全
process(std::make_shared<int>(), computePriority()); 

由于make_shared是原子操作,避免了中间状态导致的内存泄漏。

3. ​代码简洁性​

🧩 ​三、实际应用场景​

1. ​共享对象所有权​

多个shared_ptr共享同一对象,引用计数归零时自动释放:

auto obj = std::make_shared<MyClass>();
auto obj2 = obj;  // 引用计数+1
std::cout << obj.use_count(); // 输出2

对象在objobj2均析构后释放。

2. ​解决循环引用​

使用weak_ptr打破循环依赖:

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; // 弱引用,不增加计数
    b->a_ptr = a; // 强引用
    return 0; // 正确释放资源
}

若使用shared_ptr互相持有会导致内存泄漏。

3. ​高效创建数组(C++20+)​​

// C++20支持make_shared创建数组
auto arr = std::make_shared<int[]>(5); 
arr[0] = 42;

C++11/14需手动构造:std::shared_ptr<int[]>(new int[5])

⚠️ ​四、使用限制与注意事项​

不支持自定义删除器
make_shared无法指定删除器,需直接使用shared_ptr构造函数

auto ptr = std::shared_ptr<FILE>(fopen("file.txt", "r"), [](FILE* f){ fclose(f); });

延迟内存释放问题
对象内存和控制块合并分配后,若存在weak_ptr,则对象内存需等到所有weak_ptr析构才释放(强引用计数为0时仅析构对象,内存块可能未释放)。

适用场景​:对内存敏感的系统需谨慎使用。

私有构造函数限制
若类构造函数为privateprotected,需通过友元或静态工厂函数间接调用make_shared

🛠️ ​五、最佳实践建议​

💎 ​总结​

std::make_shared是现代C++内存管理的核心工具:

到此这篇关于C++ make_shared 用法小结的文章就介绍到这了,更多相关C++ make_shared内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

您可能感兴趣的文章:
阅读全文