You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

构造函数中按值传递std::string的性能探讨

现代C++中值传递string参数的性能分析

先看给定的类定义:

class MyClass
{
public:
    MyClass(std::string str) : m_str(std::move(str)) {}
private:
    std::string m_str;
};

核心结论

这种写法绝不会在任何情况下比const引用传递效率更低,反而在多数场景能拿到最优性能——对于支持移动语义、仅需将参数复制到成员变量且不在构造函数其他地方使用的场景,值传递+std::move的写法总能获得最优或持平的性能表现。

分场景性能对比

1. 传入临时字符串(如字面量、返回string的函数结果)

比如调用MyClass("hello world")或者MyClass(get_some_string()):

  • 编译器可以通过复制消除(RVO/NRVO)直接把临时字符串构造到函数参数str的内存位置,随后通过std::move把str的内容转移到成员m_str。全程只有一次字符串构造+一次无代价的移动操作,没有任何复制。
  • 如果改用const std::string&传参,构造函数内部必须执行m_str = str完成一次复制,多了一次昂贵的内存分配和数据拷贝,效率明显更低。

2. 传入左值字符串(如已存在的string变量)

比如调用std::string s = "test"; MyClass(s);:

  • 值传递会先复制一次s到参数str,再通过std::move转移到m_str,总共有一次复制+一次移动。
  • 用const std::string&传参的话,构造函数内部直接复制s到m_str,是一次复制。
  • 两者的核心复制次数完全相同,而std::move的代价极低(仅转移指针和几个整数成员),可以忽略不计,因此性能几乎没有差异。

对复制消除的补充

你提到的复制消除逻辑完全正确:

  • 若编译器未执行复制消除,值传递的复制操作发生在调用前,const引用的复制发生在构造函数内,总复制次数都是1次,性能持平。
  • 若编译器执行了复制消除,值传递写法直接跳过复制,仅用一次move完成成员初始化,比const引用写法更高效。

内容的提问来源于stack exchange,提问作者DaedalusAlpha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 22:34:56