C++11类成员初始化方式差异:类内初始化vs初始化列表
C++11类内初始化 vs 构造函数初始化列表:区别、效率与选型
针对你给出的代码示例(A类无默认构造函数,B用类内初始化A m_A{10},C用构造函数初始化列表C(): m_A(10) {}),两种初始化方式的核心区别、效率对比及选型建议如下:
核心区别
默认值的复用与覆盖规则
类内初始化是成员的默认初始化值,编译器会自动将该值插入到所有未显式初始化该成员的构造函数初始化列表中。如果某个构造函数在初始化列表里显式指定了成员的初始化值,会直接覆盖类内的默认值。比如给B新增构造函数:B(int val) : m_A(val) {}此时该构造函数创建的
m_A会使用传入的val,而非类内默认的10。而C类无类内初始化,所有构造函数必须显式在初始化列表中初始化m_A,否则会因A无默认构造函数编译报错。多构造函数场景的代码冗余度
若类存在多个构造函数,类内初始化能避免重复编写相同的初始化代码。比如B类即使有3个构造函数,只要未显式覆盖m_A的初始化,都会自动用{10}初始化;而C类的每个构造函数都得手动写m_A(10),否则编译失败。初始化逻辑的直观性
类内初始化把成员的默认值直接写在声明处,阅读代码时一眼就能看到成员的默认状态;而构造函数初始化列表的初始化逻辑分散在各个构造函数中,需要逐个查找才能明确成员的默认初始化值。
效率对比
在你给出的场景中,两种方式的效率完全一致。类内初始化本质是编译器在编译阶段,将类内的初始化逻辑自动注入到对应构造函数的初始化列表中。最终生成的汇编代码和直接写在初始化列表里的代码无任何区别,都是直接调用A(int)构造函数初始化m_A,不存在额外的拷贝、赋值操作。
选型建议
- 优先使用类内初始化:当多个构造函数对某个成员的初始化逻辑一致时,类内初始化能减少代码冗余、提升维护性,同时让默认值更直观。
- 选择构造函数初始化列表:当不同构造函数需要给成员赋予不同初始化值时,必须显式在对应构造函数的初始化列表中指定;另外,如果成员的初始化依赖构造函数的参数,也只能使用初始化列表。
内容的提问来源于stack exchange,提问作者Dominic Sesto
相关产品推荐
相关产品推荐

