当前位置: 首页 > news >正文

C++ 成员初始化机制总结笔记

1. 成员初始化的三种主要写法

以非静态成员为例,常见三种方式:

// 方式 1:声明处默认初始化
class A {
public:A();     // 可以有多个构造函数private:int a = 0;int b{1};
};// 方式 2:构造函数初始化列表
class B {
public:B(): a(0), b(1), c{2, 3}{}private:int a;int b;int c[2];
};// 方式 3:构造函数体内赋值
class C {
public:C(){a = 0;b = 1;}private:int a;int b;
};

三种方式都合法,但语义和推荐程度不同。


2. 成员声明处默认初始化(in-class member initializer)

2.1 写法示例

class Test {
public:Test();          // 构造函数可以不管 a、bprivate:int a = 0;int b{1};
};

2.2 适用范围

  • 适用于「非静态成员」:

    • 内置类型:int a = 0;
    • 类类型:std::string s = "hello";
    • const 成员:const int x = 42;
    • 引用成员:int& r = someGlobal;
  • 不适用于普通 static 数据成员
    静态成员不属于某个对象实例,它有单独的初始化规则(见后面)。

2.3 作用规则

对于每个构造函数:

  • 如果构造函数初始化列表中没有提到该成员
    • 使用声明处的默认初始化式。
  • 如果构造函数初始化列表中显式初始化该成员
    • 以初始化列表为准,声明处默认值对这个构造函数无效。

示例:

class Test {
public:Test() = default;        // 使用 a = 0Test(int x) : a(x) {}    // 使用 a(x)private:int a = 0;
};
  • Test t1;a 初始化为 0
  • Test t2(5);a 初始化为 5

2.4 使用建议

  • 表达「这个成员的通常默认状态」时,可以写在声明处。
  • 多个构造函数都需要同一个默认值时,声明处初始化能减少重复。

3. 构造函数初始化列表

3.1 写法示例

class Test {
public:Test(): a(0), b(1), c{2, 3}{}private:int a;int b;int c[2];
};

3.2 适用范围

可以在初始化列表中初始化:

  • 直接基类子对象:
    class Base {};
    class Derived : public Base {
    public:Derived() : Base() {}
    };
    
  • 非静态成员(包括):
    • 普通成员
    • const 成员
    • 引用成员
    • 无默认构造函数的类成员

不能在初始化列表中初始化:

  • static 成员(它们不属于具体对象实例)。

3.3 初始化列表 vs 声明处默认值

如果两者同时存在:

class Test {
public:Test() : a(2) {}  // 初始化列表private:int a = 1;        // 声明处默认值
};

行为是:

  • Test::Test() 这个构造函数来说:
    • a 只会被初始化一次,用的是 a(2)
    • a = 1 这条默认初始化式在这个构造函数里被忽略

不会出现“先按声明处初始化为 1,再按初始化列表改为 2”这种两次初始化。

可以总结为:

对于同一个成员,编译器在生成构造函数时只会为它选择一个初始化式:
优先用初始化列表,缺失时才用声明处默认值。


4. 构造函数体内赋值

4.1 写法示例

class Test {
public:Test(){a = 0;b = 1;}private:int a;int b;
};

4.2 实际发生了什么

对于 ab

  1. 在进入构造函数体前,成员已经被「默认初始化」:
    • 对内置类型(int 等):值未定义(不自动变 0)。
    • 对类类型:调用默认构造函数。
  2. 在构造函数体内,你再执行一次赋值操作(operator=)。

int 这样的标量,最终结果是你期待的值,但中间有一段「未定义值」的阶段。
std::string 等类类型,则多了一次「构造 + 赋值」,不如初始化列表一次构造干净。

4.3 使用建议

  • 不推荐用构造函数体内赋值来做「第一次初始化」。
  • 更适合做后续逻辑处理,而不是成员的初始构造。

5. 成员构造 / 析构顺序

5.1 顺序规则

构造顺序:按「成员在类中声明的顺序」构造。
析构顺序:按「声明顺序的反向」析构。

示例:

class Holder {
public:Holder(): r1("r1"), r2("r2"){}private:FakeResource r1;FakeResource r2;
};

无论你在初始化列表里先写 r2 还是 r1,真正的顺序始终是:

  • 构造:先 r1,后 r2
  • 析构:先 r2,后 r1

5.2 工程意义

  • 有依赖关系的成员,要按依赖从上到下声明
    • 被依赖的在前,依赖者在后。
  • 初始化列表的顺序建议与声明顺序保持一致,避免误导阅读者。

6. static 成员单独说明

static 数据成员的初始化规则与普通成员不同:

  • inline 的静态数据成员,一般需要在类外定义并初始化:

    class A {
    public:static int counter;
    };int A::counter = 0;   // 类外定义 + 初始化
    
  • C++17 引入 inline static,可以在类内直接定义并初始化:

    class A {
    public:inline static int counter = 0;
    };
    

静态成员不参与每个对象的构造/析构,所以:

  • 与「成员声明处默认值 / 初始化列表」的讨论不是同一维度的问题;
  • 初始化列表不能初始化静态成员。

7. 实践建议小结

可以整理成几条简单的习惯:

  1. 成员的第一次合法状态

    • 优先在「成员声明处 + 初始化列表」完成。
    • 不要依赖构造函数体内赋值做首次初始化。
  2. 声明处默认值

    • 表达成员的「默认状态」,对所有构造函数生效。
    • 某个构造函数需要特殊值时,用初始化列表覆盖。
  3. 初始化列表

    • 用于基类、const 成员、引用成员、无默认构造的成员。
    • 用于类类型成员时,一步构造,避免「默认构造 + 赋值」的多余操作。
  4. 顺序

    • 成员构造/析构顺序只看「声明顺序」,不看初始化列表写的顺序。
    • 有依赖关系时,按照依赖关系调整声明顺序。
  5. static 成员

    • 把它当成「类作用域的全局变量」,按静态对象规则初始化。
    • 不参与普通对象的构造/析构,不在初始化列表里出现。

按这套规则写代码,既能避免初始化顺序/重复操作的误解,又能把成员初始化的行为控制在预期之内。

http://www.jsqmd.com/news/312972/

相关文章:

  • 信号去噪天花板?SSA-VMD+皮尔逊+小波阈值:一套组合拳搞定复杂噪声
  • 信息安全通关指南:一份硬核全景解读,打通技术实战、管理流程与法规遵从的多维能力
  • MinIO最新稳定版本说明
  • Linux 进程脱离父进程控制设置方法
  • 2026最新商用/学校/单位厨房设计推荐!西南地区优质厨房设计服务权威榜单发布,助力打造高效安全厨房空间
  • 2026年别墅/室内/老旧小区/液压式/载货电梯推荐:厦门德菱电梯工程有限公司全系解决方案
  • 2026年 CentOS 6 强制安装 GCC 及 Yum 源修复全记录
  • 2026年花生油品牌推荐:乳山市金果食品股份有限公司,知名/优质/有机/高油酸花生油全系供应
  • 【信号去噪】SSA-VMD麻雀搜索算法优化变分模态分解+皮尔逊系数+小波阈值降噪+信号重构,MATLAB代码
  • 2026最新厨房平面设计推荐!学校/食堂/单位厨房设计权威方案发布,专业团队打造高效安全厨房空间
  • 2026年耐酸/衬四氟/防腐/氟塑料/不锈钢磁力泵厂家推荐:上海梭川泵阀全系解决方案
  • 狠心卸载了 VS Code!Cursor + DeepSeek 才是 2026 年程序员的终极形态(真香预警)
  • 【收藏不亏】大模型学习进阶指南:从入门到实战避坑全攻略
  • 巧用Node.js REPL自定义提示符和命令技巧
  • 承德英语雅思培训机构推荐,2026权威测评出国雅思辅导机构口碑榜
  • 2026油烟净化设备厂家推荐:广州净平环保科技,全系产品适配餐饮/商用场景解决方案
  • 收藏!大模型工程化岗位薪资暴涨,3年经验总包60W+,从0到1实战指南来了
  • 2026年纳倍特壁挂炉推荐:全预混/燃气/电壁挂炉,节能环保与安全可靠兼具之选
  • 【必收藏】2026 AI新风向:世界模型×具身智能,解锁大模型物理世界落地密码
  • 2026年二手三坐标设备推荐:青岛科恩机电设备有限公司,九成新三坐标销售与回收服务
  • 【收藏级】大模型学习全路径:从零基础到实战落地,程序员转型必看
  • 2026气流粉碎机厂家推荐:潍坊市友信粉体设备有限公司,超微/食品/石墨/大型/扁平式粉碎机全系供应
  • 2026年螺旋输送机厂家推荐:无锡市长荣输送机械有限公司,全系列螺旋输送设备专业供应
  • 2026年冷热冲击试验箱厂家推荐:广东艾思荔检测仪器,多规格/高精度设备助力检测升级
  • 2026年VPSA/PSA制氧设备厂家推荐:无锡永业气体设备公司,高效稳定制氧解决方案
  • LANGFUSE Docker 容器化部署指南 - 指南
  • 【课程设计/毕业设计】基于ssm+Android的学籍异动管理平台涵盖学生、教师、课程、班级、成绩、排课、选课、学籍、考勤、教学计划、教学资源【附源码、数据库、万字文档】
  • 企业所得税按年计征、分季预缴(1月、4月、7月、10月)、年度汇算清缴(次年5月31日前);
  • 期刊抗衰老重磅发现:W+端粒塔核心逻辑破局,NMN能驱动免疫细胞年轻20岁
  • 2026最新双壁热缩管推荐!新能源汽车/航天航空/医疗行业专用热缩管权威榜单发布,合规品质双保障助力高端领域绝缘防护