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

为何C++类构造函数使用初始化列表而非函数体内赋值?

为什么C++构造函数里要用成员初始化列表而非函数体内赋值?

你提到的第一种写法叫做成员初始化列表,它和函数体内赋值的核心区别在于执行时机与底层逻辑,下面给你拆解清楚:

1. 效率差异(针对非内置类型)

对于std::string这类类类型成员:

  • 用初始化列表m_Name(name):直接调用std::string的拷贝构造函数,一步到位用name的值初始化m_Name,没有多余操作。
  • 在函数体内赋值m_Name = name:会先调用std::string的默认构造函数创建空字符串,再调用赋值运算符把name的值赋给它,多了一次默认构造的开销。虽然std::string的默认构造开销不大,但对更复杂的自定义类,这个效率差异会很明显。

2. 某些场景下必须用初始化列表

有几种情况,你根本没法用函数体内赋值,只能依赖初始化列表:

  • 成员被const修饰:比如const std::string m_Name,const对象必须在创建时初始化,不能后续赋值。
  • 成员是引用类型:比如std::string& m_Name,引用必须在声明时绑定对象,不能先默认创建再赋值。
  • 成员类没有默认构造函数:如果你的成员是某个自定义类,且该类只提供带参数的构造函数,那必须用初始化列表传参构造它。
  • 基类没有默认构造函数:比如Player继承的Entity如果只有带参数的构造函数,Player的构造函数必须用初始化列表给Entity传参,否则编译报错。

3. 代码风格与一致性

不管成员是内置类型(int、double)还是类类型,统一用初始化列表的话,代码风格更一致,也能避免遗漏某些必须初始化的成员(比如const、引用),减少潜在的编译错误。

两种写法的执行流程对比

初始化列表写法

Player(const std::string& name)
    : m_Name(name) {}
  1. 进入构造函数体之前,先初始化所有类成员:调用m_Name的拷贝构造函数,用name完成初始化。
  2. 执行构造函数体(此处为空)。

函数体内赋值写法

Player(const std::string& name)
{
    m_Name = name;
}
  1. 进入构造函数体之前,先默认初始化所有类成员:调用m_Name的默认构造函数,创建空字符串。
  2. 执行构造函数体,调用m_Name的赋值运算符,把name的值赋给它。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 14:47:37