首页 > 后端开发 > C++ > `make_shared` 与构造函数初始化的 `shared_ptr`:性能和异常安全性有何区别?

`make_shared` 与构造函数初始化的 `shared_ptr`:性能和异常安全性有何区别?

Barbara Streisand
发布: 2024-12-11 00:40:16
原创
403 人浏览过

`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中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板