首页/新闻资讯/正文详情

第22节 构造函数与初始化列表:解决const、引用成员初始化坑点

发布时间:2026/9/25 18:40:28 来源:云帆数科 栏目:资讯中心
第22节 构造函数与初始化列表:解决const、引用成员初始化坑点
承接上文上一节学习了类的成员变量、成员函数与工程编码规范我们发现对象创建后成员变量默认是随机垃圾值需要手动调用setter赋值。本节学习构造函数对象创建时自动执行的特殊成员函数再深入初始化列表解决普通函数体内无法初始化const成员、引用成员的硬性语法问题掌握对象初始化底层逻辑。学习说明构造函数是面向对象里对象生命周期的起点。很多新手分不清在构造函数函数体内赋值和初始化列表初始化有本质区别。 函数体内是赋值操作初始化列表才是真正的初始化。const成员、引用成员必须在初始化列表完成初始化不能在函数体内赋值这是本节核心难点。本节学习目标掌握构造函数基础语法、调用时机、构造函数特征理解默认构造函数以及自定义构造后默认构造消失的规则学会初始化列表写法分清初始化 vs 赋值的本质差异掌握const成员、引用成员为什么只能用初始化列表初始化掌握初始化列表的执行顺序和书写顺序无关按成员声明顺序初始化一、构造函数基础核心特点函数名和类名完全相同没有返回值连void都不能写对象创建的一瞬间自动调用无法手动调用可以重载多个构造函数参数列表不同如果自己不写任何构造编译器自动生成默认无参构造只要手写任意构造函数编译器不再提供默认构造#include iostream #include string using namespace std; class Person { private: string m_name; int m_age; public: // 无参构造函数 Person() { cout 无参构造函数执行 endl; m_name 未知; m_age 0; } // 有参构造函数构造重载 Person(string name, int age) { cout 有参构造函数执行 endl; m_name name; m_age age; } void showInfo() { cout m_name m_age endl; } }; int main() { Person p1; // 自动调用无参构造 Person p2(李四, 25); // 自动调用有参构造 p1.showInfo(); p2.showInfo(); return 0; }上面写法是构造函数体内赋值不是初始化。普通成员可以这么写但const、引用成员不支持这种写法。补充验证示例手写有参构造后默认构造消失#include iostream #include string using namespace std; class Person { public: Person(string name) { cout 有参构造执行 endl; } }; int main() { Person p1(张三); // 正确 // Person p2; // 编译报错手写构造后编译器不再生成默认无参构造 return 0; }C11 default显式生成默认构造进阶示例#include iostream #include string using namespace std; class Person { private: string m_name; public: Person(string name) { m_name name; } Person() default; // 显式告诉编译器生成默认无参构造 }; int main() { Person p1(张三); Person p2; // 正常编译运行 return 0; }二、初始化列表语法初始化列表写在构造函数参数括号后面、函数体{}之前用冒号开头。#include iostream #include string using namespace std; class Person { private: string m_name; int m_age; public: // 初始化列表写法 Person(string name, int age) : m_name(name), m_age(age) { cout 初始化列表执行完成进入构造函数体 endl; } void showInfo() { cout m_name m_age endl; } }; int main() { Person p(王五, 30); p.showInfo(); return 0; }核心规则初始化列表先执行然后才进入构造函数大括号内部初始化 创建变量同时给初始值函数体内 变量已经创建完成再修改值赋值三、重点const成员、引用成员只能使用初始化列表const变量、引用变量定义的时候就必须初始化一旦创建完成后续不能赋值。 放到构造函数体内时成员已经完成创建此时再赋值直接编译报错。只能在初始化列表阶段完成初始化。#include iostream using namespace std; class Test { private: const int m_a; // const成员必须初始化 int m_ref; // 引用成员必须初始化 public: // 只能在初始化列表初始化 const 和引用成员 Test(int val) : m_a(100), m_ref(val) { // m_a 200; // 错误const不能赋值 // m_ref val; // 错误引用已经绑定不能在这里初始化 } }; int main() { int val 42; Test t(val); // m_a 100, m_ref绑定到变量val return 0; }四、初始化列表容易踩坑初始化顺序⚠️初始化顺序由成员在类中声明的先后顺序决定和初始化列表书写顺序无关这是高频隐蔽bug。#include iostream using namespace std; class Demo { private: int m_x; int m_y; public: Demo(int val) : m_y(val), m_x(m_y) { // 先初始化m_x再初始化m_y // m_x(m_y) 此时m_y还未初始化m_x得到随机垃圾值 cout m_x m_x m_y m_y endl; } }; int main() { Demo d(10); // 输出m_x随机值 m_y10 // 因为先初始化m_x(m_y)此时m_y还未初始化 return 0; }坑点说明列表写的是先m_y再m_x但类内声明顺序是m_x在前程序优先初始化m_x此时m_y还没赋值导致m_x为随机值。五、工程编码推荐✅ 推荐优先使用初始化列表初始化所有成员而不是构造体内赋值语法统一同时支持普通成员、const成员、引用成员对于自定义类型成员减少一次临时对象拷贝性能更好代码可读性强一眼看清对象创建时各个成员初始值❌ 不推荐全部放到构造函数体内赋值仅简单Demo可以使用性能对比示例用于思考题#include iostream #include string using namespace std; class Student { private: string m_name; public: // 写法A函数体内赋值 Student(string name) { m_name name; // 先默认构造m_name再赋值两次操作 } // 写法B初始化列表 Student(string name) : m_name(name) { } // 直接初始化一次操作 };六、高频坑点总结手写任意构造函数后编译器不再提供默认无参构造。再写Person p;会编译报错。区分初始化列表是初始化函数体内代码是赋值二者本质不一样。const成员、引用成员只能在初始化列表初始化构造函数体内赋值直接编译失败。初始化列表执行顺序 ≠ 书写顺序按类内成员声明顺序初始化极易写出隐藏bug。七、本节思考题写了一个有参构造函数再定义Person p;为什么编译报错const成员变量能不能在构造函数{}里面赋值为什么初始化列表里面成员的初始化顺序是按列表书写顺序还是类内声明顺序举个例子。对比上面Student类的写法A和写法B二者有什么区别为什么工程上推荐写法B下期预告下一节析构函数实战内存释放场景与手写规范。

相关推荐

学信奥的孩子有哪些数学优势
学信奥的孩子有哪些数学优势

学信奥的孩子,会在数学能力上形成6项普通校内学习很难练到的差异化优势,完全适配你家四年级孩子的理科成长节奏: 🧩 问题拆解能力远超同龄人 信奥题不会像校内数学那样把知识点直接标出来,而是把多类数学考点揉成复杂现… · 2026/9/25 18:40:22

免费安全的 - 二维码转换工具
免费安全的 - 二维码转换工具

AI编写小工具还是很方便的,做了一个二维码转换器,可以直接生成二维码,也可以安全的扫描二维码,展示二维码嵌入的文本信息。 欢迎大家尝试! 演示地址(多语言版)https://env-00jy6ton3kte-stati… · 2026/9/25 18:40:16

MySQL+Qt医疗预约系统源码解析与数据库设计实战
MySQL+Qt医疗预约系统源码解析与数据库设计实战

简介:这是一份基于MySQL和Qt开发的医疗预约系统完整项目,适合计算机相关专业学生用于课程大作业、毕业设计或初期项目立项演示。压缩包共22个文件,以cpp、h、ui、qrc等Qt工程文件为核心,配合png、jpg图片展示数据库表设计、ER图、… · 2026/9/25 18:40:09

基于昇腾Atlas 300V 24G推理卡的YOLO模型部署与调优实践
基于昇腾Atlas 300V 24G推理卡的YOLO模型部署与调优实践

前阵子团队准备把一套基于YOLOv5的检测服务从GPU服务器迁移到昇腾Atlas上,群里讨论最多的一句话就是:“atlas 300v 24g是运算加速卡吗?”我当时也愣了一下。后来翻完产品文档、踩了一周坑,才算把这卡的脾气摸清楚。如果你也是第一… · 2026/9/25 19:09:58

AllData数据中台集成DB-GPT:构建自然语言查询与多模态数据交互的智能数据问答系统
AllData数据中台集成DB-GPT:构建自然语言查询与多模态数据交互的智能数据问答系统

1. 数据中台与AI多模态数据库的融合背景1.1 从“数据孤岛”到“智能资产”的演进逻辑做过数据中台的人都有一个共同的痛:数据接进来了,表建好了,指标跑通了,但业务方还是不会用。他们不想写SQL,不想看BI看板&#xff0… · 2026/9/25 19:09:58

DEAP脑电情绪二分类实战:从EDF加载到XGBoost建模
DEAP脑电情绪二分类实战:从EDF加载到XGBoost建模

简介:本资源是一套基于DEAP脑电数据集的轻量级脑电情绪二分类实践方案,面向人工智能初学者、生物医学工程入门者及机器学习爱好者,聚焦情绪识别这一典型小样本分类任务。项目完整覆盖信号处理(FFT频域转换)、特征预处理… · 2026/9/25 19:09:58

人AB血清如何从科研走到IND/BLA?CGT原辅料资料包与DMF路径完整解析
人AB血清如何从科研走到IND/BLA?CGT原辅料资料包与DMF路径完整解析

摘要: CGT项目中的人AB血清选型不仅影响T细胞、NK细胞等细胞扩增,也会直接影响后续IND/BLA阶段的CMC资料准备。如果项目早期只按照细胞生长表现和采购价格选择血清,进入临床开发后才发现材料来源、供体控制、病原体安全、质量文件或DMF支持不… · 2026/9/25 19:09:46

实时Linux为什么要隔离内核?从系统调用到内核抢占,看懂硬实时系统的最后一道实时性边界
实时Linux为什么要隔离内核?从系统调用到内核抢占,看懂硬实时系统的最后一道实时性边界

前面的文章我们一直在讨论一个核心问题:如何让实时任务不被其他任务干扰?从CPU核心隔离,到IRQ隔离;从内存、Cache、DMA等资源控制,到实时IPC;再到Watchdog和故障隔离,我们实际上已经逐渐建立起了… · 2026/9/25 19:09:33

用Trae把原型图变成可执行HTML:TaoToken统一Key接入AI编程工作流
用Trae把原型图变成可执行HTML:TaoToken统一Key接入AI编程工作流

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 19:09:27

数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)
数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31

创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战
创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31

MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX
MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:37

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码