make_shared真的比new更高效吗?

2024-04-07

我正在尝试shared_ptr and make_shared从 C++11 编写了一个小玩具示例来看看调用时实际发生了什么make_shared。作为基础设施,我使用 llvm/clang 3.0 以及 XCode4 中的 llvm std c++ 库。

class Object
{
public:
    Object(const string& str)
    {
        cout << "Constructor " << str << endl;
    }

    Object()
    {
        cout << "Default constructor" << endl;

    }

    ~Object()
    {
        cout << "Destructor" << endl;
    }

    Object(const Object& rhs)
    {
        cout << "Copy constructor..." << endl;
    }
};

void make_shared_example()
{
    cout << "Create smart_ptr using make_shared..." << endl;
    auto ptr_res1 = make_shared<Object>("make_shared");
    cout << "Create smart_ptr using make_shared: done." << endl;

    cout << "Create smart_ptr using new..." << endl;
    shared_ptr<Object> ptr_res2(new Object("new"));
    cout << "Create smart_ptr using new: done." << endl;
}

现在请看一下输出:

使用 make_shared 创建 smart_ptr...

构造函数 make_shared

复制构造函数...

复制构造函数...

析构函数

析构函数

使用 make_shared 创建 smart_ptr:完成。

使用新创建 smart_ptr...

新建构造函数

使用 new:done 创建 smart_ptr。

析构函数

析构函数

看起来make_shared调用复制构造函数两次。如果我为一个分配内存Object使用常规的new这不会发生,只有一个Object被建造。

What I am wondering about is the following. I heard that make_shared is supposed to be more efficient than using new(1 http://en.cppreference.com/w/cpp/memory/shared_ptr/make_shared, 2 http://channel9.msdn.com/Events/GoingNative/GoingNative-2012/STL11-Magic-Secrets). One reason is because make_shared allocates the reference count together with the object to be managed in the same block of memory. OK, I got the point. This is of course more efficient than two separate allocation operations.

相反,我不明白为什么这必须伴随两次调用复制构造函数的成本Object。因此我不相信make_shared比使用分配更有效new in every案件。我这里错了吗?好吧,我们可以实现一个移动构造函数Object但我仍然不确定这是否比仅仅分配更有效Object通过new。至少不是在所有情况下都是如此。如果复制的话那就是真的Object比为引用计数器分配内存更便宜。但是shared_ptr- 内部引用计数器可以使用几种原始数据类型来实现,对吧?

你能帮忙解释一下原因吗make_shared尽管有概述的复制开销,但就效率而言,这是可行的方法吗?


作为基础设施,我使用 llvm/clang 3.0 以及 XCode4 中的 llvm std c++ 库。

嗯,这似乎是你的问题。 C++11 标准规定了以下要求make_shared<T> (and allocate_shared<T>),第 20.7.2.2.6 节:

要求:表达式 ::new (pv) T(std::forward(args)...) 的格式应正确,其中 pv 具有 void* 类型并指向适合保存 T 类型对象的存储。 A 应是分配器(17.6.3.5)。 A 的复制构造函数和析构函数不应抛出异常。

T is not要求可复制构造。的确,T甚至不需要是非放置新可构造的。只需要可就地构建即可。这意味着唯一的事情是make_shared<T>可以做T is new它就位。

所以你得到的结果与标准不符。 LLVM 的 libc++ 在这方面是有问题的。提交错误报告。

作为参考,以下是我将你的代码导入 VC2010 时发生的情况:

Create smart_ptr using make_shared...
Constructor make_shared
Create smart_ptr using make_shared: done.
Create smart_ptr using new...
Constructor new
Create smart_ptr using new: done.
Destructor
Destructor

我也将其移植到Boost的原始版本中shared_ptr and make_shared,我得到了和VC2010一样的东西。

我建议提交一份错误报告,因为 libc++ 的行为已被破坏。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

make_shared真的比new更高效吗? 的相关文章

  • 使用 std::packaged_task/std::exception_ptr 时,线程清理程序报告数据争用

    我遇到了线程清理程序 TSan 的一些问题 抱怨某些生产代码中的数据争用 其中 std packaged task 通过将它们包装在 std function 中而移交给调度程序线程 对于这个问题 我简化了它在生产中的作用 同时触发 TSa
  • 在 C++ 中使用 matlab 结构(matlab 函数调用的返回值)(由 matlab 编译器生成的库)

    你好 我有一个相当简单的 matlab 函数 例如 function MYSTRUCT myfunc MYSTRUCT prop1 test MYSTRUCT prop2 foo MYSTRUCT prop3 42 end 我用 matla
  • 如何在c++中读取pcap文件来获取数据包信息?

    我想用 C 编写一个程序来读取 pcap 文件并获取数据包的信息 例如 len sourc ip flags 等 现在我找到了如下代码 我认为它会帮助我获取信息 但是我有一些疑问 首先我想知道应该将哪个库添加到我的程序中 然后什么是 pca
  • 如何将 protobuf-net 与不可变值类型一起使用?

    假设我有一个像这样的不可变值类型 Serializable DataContract public struct MyValueType ISerializable private readonly int x private readon
  • 确保 StreamReader 不会挂起等待数据

    下面的代码读取从 tcp 客户端流读取的所有内容 并且在下一次迭代中它将仅位于 Read 上 我假设正在等待数据 我如何确保它不会在没有任何内容可供读取时返回 我是否必须设置低超时 并在失败时响应异常 或者有更好的办法吗 TcpClient
  • 复制 std::function 的成本有多高?

    While std function是可移动的 但在某些情况下不可能或不方便 复制它会受到重大处罚吗 它是否可能取决于捕获变量的大小 如果它是使用 lambda 表达式创建的 它依赖于实现吗 std function通常被实现为值语义 小缓
  • 为什么极端下派生类(多重虚拟继承)的大小包括超类成员大小的两倍?

    include
  • 单个对象的 Monogame XNA 变换矩阵?

    我读过一些解释 XNA Monogame 变换矩阵的教程 问题是这些矩阵应用于 SpriteBatch Begin matrix 这意味着所有 Draw 代码都将被转换 如何将变换矩阵应用于单个可绘制对象 就我而言 我想转换滚动背景 使其自
  • 使用接口有什么好处?

    使用接口有什么用 我听说它用来代替多重继承 并且还可以用它来完成数据隐藏 还有其他优点吗 哪些地方使用了接口 程序员如何识别需要该接口 有什么区别explicit interface implementation and implicit
  • 具有交替类型的可变参数模板参数包

    我想知道是否可以使用参数包捕获交替参数模式 例如 template
  • 使用自定义堆的类似 malloc 的函数

    如果我希望使用自定义预分配堆构造类似 malloc 的功能 那么 C 中最好的方法是什么 我的具体问题是 我有一个可映射 类似内存 的设备 已将其放入我的地址空间中 但我需要获得一种更灵活的方式来使用该内存来存储将随着时间的推移分配和释放的
  • C#:帮助理解 UML 类图中的 <>

    我目前正在做一个项目 我们必须从 UML 图编写代码 我了解 UML 类图的剖析 但我无法理解什么 lt
  • 如何禁用 fread() 中的缓冲?

    我正在使用 fread 和 fwrite 读取和写入套接字 我相信这些函数用于缓冲输入和输出 有什么方法可以在仍然使用这些功能的同时禁用缓冲吗 Edit 我正在构建一个远程桌面应用程序 远程客户端似乎 落后于服务器 我不知道可能是什么原因
  • C# 中的合并运算符?

    我想我记得看到过类似的东西 三元运算符 http msdn microsoft com en us library ty67wk28 28VS 80 29 aspx在 C 中 它只有两部分 如果变量值不为空 则返回变量值 如果为空 则返回默
  • 为什么 std::strstream 被弃用?

    我最近发现std strstream已被弃用 取而代之的是std stringstream 我已经有一段时间没有使用它了 但它做了我当时需要做的事情 所以很惊讶听到它的弃用 我的问题是为什么做出这个决定 有什么好处std stringstr
  • 使用管道时,如果子进程数量大于处理器数量,进程是否会被阻塞?

    当子进程数量很大时 我的程序停止运行 我不知道问题是什么 但我猜子进程在运行时以某种方式被阻止 下面是该程序的主要工作流程 void function int process num int i initial variables for
  • 如何设置 log4net 每天将我的文件记录到不同的文件夹中?

    我想将每天的所有日志保存在名为 YYYYMMdd 的文件夹中 log4net 应该根据系统日期时间处理创建新文件夹 我如何设置它 我想将一天中的所有日志保存到 n 个 1MB 的文件中 我不想重写旧文件 但想真正拥有一天中的所有日志 我该如
  • 动态添加 ASP.Net 控件

    我有一个存储过程 它根据数据库中存储的记录数返回多行 现在我想有一种方法来创建 div 带有包含该行值的控件的标记 如果从数据库返回 10 行 则 10 div 必须创建标签 我有下面的代码来从数据库中获取结果 但我不知道如何从这里继续 S
  • 按 Esc 按键关闭 Ajax Modal 弹出窗口

    我已经使用 Ajax 显示了一个面板弹出窗口 我要做的是当用户按 Esc 键时关闭该窗口 这可能吗 如果有人知道这一点或以前做过这一点 请帮助我 Thanks 通过以下链接 您可以通过按退出按钮轻松关闭窗口 http www codepro
  • WebSocket安全连接自签名证书

    目标是一个与用户电脑上安装的 C 应用程序交换信息的 Web 应用程序 客户端应用程序是 websocket 服务器 浏览器是 websocket 客户端 最后 用户浏览器中的 websocket 客户端通过 Angular 持久创建 并且

随机推荐

  • 添加 const 泛型时的“不受约束的泛型常量”

    我如何添加 const 泛型 假设我有一个 foo 类型 pub struct foo
  • 如果类型参数的顺序错误,是否可以将类型设为类的实例?

    考虑以下类型 data SomeType m a SomeType m Integer a 我们可以使用以下代码轻松地将该类型设为 Functor 的实例 instance Functor SomeType m where fmap f S
  • 使用递归函数进行并行编程?

    问题背景 我正在尝试编写一个利用多核处理器和并行处理的难题解决算法 然而 理想 最简单的解决方案是简单的递归函数 分解解决方案以利用并行处理的最佳方法是什么AND递归函数 下面的代码是一个简单的解谜算法的解决方案 它工作正常 此示例中的谜题
  • 如何使用java将阿拉伯语单词插入mysql数据库

    我有一个java应用程序 想要将阿拉伯语单词插入mysql数据库 我的代码如下 Connection con null String url jdbc mysql localhost String db students String dr
  • 如何自定义 YouTube 视频的结束时间?

    我正在尝试弄清楚如何为嵌入的 YouTube 视频指定自定义结束时间 我知道我可以通过添加来自定义开始时间开始 30 但我还没有看到任何与结束时间有关的内容 我需要能够为我正在构建的网络应用程序执行此操作 因此如果 YouTube 无法提供
  • Jekyll 插件不工作

    我开发了一个简单的 Jekyll 插件 用于生成类别页面 它在我的本地系统上运行良好 但在 github 站点上不起作用 这是插件的来源 https github com madhur madhur github com blob mast
  • 对于新 XPage 开发人员来说,最重要的 3 个 XPage 性能技巧是什么?

    您会告诉刚接触 XPage 的开发人员做哪 3 件事 以帮助最大限度地提高 XPage 应用程序的性能 Tim Tripcony 给出了很多建议
  • 如何使用 Drive Rest API 读取云端硬盘照片

    我正在尝试使用 Google Apps 脚本中的 Drive REST API 读取 Google Photos 代码如下所示 function myFunction var files Drive Files list maxResult
  • Microsoft.Owin.Cors 中间件与 ASP.NET Web Api 2.0 一起使用时会做什么?

    我有一个带有令牌身份验证的 ASP NET Web Api 2 0 项目 所有内容主要按照本文完成 使用 ASP NET Web API 2 Owin 和 Identity 进行基于令牌的身份验证 http bitoftech net 20
  • ASP.NET MVC 性能

    我发现一些疯狂的评论称 ASP NET MVC 比 ASP NET WebForms 快 30 倍 真正的性能差异是什么 是否经过测量以及性能优势是什么 这是为了帮助我考虑从 ASP NET WebForms 迁移到 ASP NET MVC
  • 将 Docker 容器限制为单个 cpu 核心

    我正在尝试构建一个在一致条件下运行代码片段的系统 我认为实现这一点的一种方法是在具有相同布局的 docker 容器中运行各种程序 保留相同数量的内存等 但是 我似乎不知道如何保持 CPU 使用率一致 我似乎能找到的最接近的是 cpu 共享
  • 压缩过滤器+MVC+Yahoo YSlow

    我一直在使用雅虎的 YSLOW 来尝试让我的页面运行得更快AgentX http www agentx co nz 我正在使用下面的压缩过滤器 当我通过 Visual Studio 运行该网站时 YSLOW 说所有文件都已压缩 当我查看实时
  • C#:从 XML 读取/写入日期时间

    我需要知道写作 阅读的最佳方式DateTime传入 传出 XML 我应该直接写吗DateTime转换为 XML 或DateTime ToString 转换为 XML 第二个问题是如何从 XML 中读取日期元素 铸造可以用于此目的吗 例如 D
  • RxJS (5.0rc4):暂停和恢复间隔计时器

    我正在使用 Rx 来保持动画时钟 每个动画帧都会将间隔刻度映射到该刻度的新值 假设我想暂停动画 最自然的方法是以某种方式暂停时钟接收 然后在稍后恢复它 取消订阅然后重新订阅并不是一个自然的选择 因为这个动画时钟是一个冷可观察的对象 我不想在
  • 如何使用 QtMqtt 和 SSL 执行安全 MQTT?

    我正在尝试使用 QtMQtt 示例项目 simpleclient 但我想执行安全的 MQTT 我该如何处理这个问题 我读过这篇博客 https www qt io blog 2017 08 14 introducing qtmqtt pro
  • 如何区分应用程序退出和系统关闭

    Mac OS X 上的 Java 在 Swing GUI 应用程序中 我想区分应用程序退出和系统关闭 在应用程序退出时 我想显示一个确认对话框 但是当用户选择 系统关闭 时 我只想退出应用程序 因为系统已经出现了一个确认对话框 这在其他平台
  • Python 中的意外列表行为

    我想颠倒一个列表 我成功地做到了 但在工作的过程中我发现了一些奇怪的事情 以下程序按预期工作 但未注释行list reversed i list len list 1 i and 打印 列表 i 评论最后一行当然 导致了改变list 我没看
  • 使用 setInterval() 后出现clearInterval() 未定义错误

    我知道这不应该是内联的 但 YUI 库的对话框迫使我这样做 我的问题是 每当我将鼠标悬停在该 div 上时 左边缘滚动就会激活 但当我将鼠标移出该 div 时 它不会停止 JS 控制台报告 未捕获的引用错误 timerID 未定义 这是代码
  • 如何从 MQTT 生产并在 ActiveMQ 中作为 MQTT 和 JMS 消费

    我有一个设置 其中消息作为 MQTT 生成到 ActiveMQ 我有两个消费者 一个作为 JMS 另一个作为 MQTT 当我将消息作为 JMS 消息发布到主题 foo 时 我在 JMS 和 MQTT 消费者处都收到消息 但是当我在同一主题上
  • make_shared真的比new更高效吗?

    我正在尝试shared ptr and make shared从 C 11 编写了一个小玩具示例来看看调用时实际发生了什么make shared 作为基础设施 我使用 llvm clang 3 0 以及 XCode4 中的 llvm std