新闻详情

新闻详情

首页 / 资讯中心 / 详情

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

发布时间:2026/9/25 18:40:31来源:尧图网络
第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下期预告下一节析构函数实战内存释放场景与手写规范。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

一分钟信创网盘自主搭建(下) 2026/9/25 19:25:50

一分钟信创网盘自主搭建(下)

背景 上期文章咱们讲述了如何把本地文件通过DESK倚天剑的WebDAV网盘功能对外分享。今天咱们来点更高级的,把远程文件通过DESK倚天剑的网盘技术对外分享。强烈建议大家先看一下上期文章,直接看本期文章很容易看糊涂了。 DESK倚天剑的WebDAV网盘 DESK倚…

阅读更多 →
私有部署双链笔记:Docker部署与个人博客搭建实战 2026/9/25 19:25:43

私有部署双链笔记:Docker部署与个人博客搭建实战

简介:这是一款支持私有部署的云端存储双链笔记软件,面向重视数据安全与知识管理的个人用户及开发者,同时集成个人博客功能,可在 Windows、Mac、网页客户端与移动端之间无缝切换。资源包共 1023 个文件,约 23.74MB&…

阅读更多 →
Win11窗口级输入法隔离:程序员高效编码必备设置 2026/9/25 19:25:30

Win11窗口级输入法隔离:程序员高效编码必备设置

1. 项目概述:为什么程序员真的需要“窗口级输入法隔离”你有没有过这种体验:在 VS Code 里敲着 Python 代码,手一滑按了 CtrlSpace,结果弹出的是中文候选框,光标卡在函数名中间;切到 Chrome 写技术文档时&a…

阅读更多 →
SIMPLEX洗脑电音实战:构建批量音频循环与API处理链 2026/9/25 19:25:30

SIMPLEX洗脑电音实战:构建批量音频循环与API处理链

这次我们来看一个音频处理向的题目:SIMPLEX 洗脑电音。简单说,SIMPLEX 式的做法就是把任意一段音频素材快速改造成"循环、重复、强记忆点"的电音片段,让听感在十几秒内被一个 Hook 牢牢粘住。短视频 BGM、广告配乐、游戏提示音、直…

阅读更多 →
SQL Server PIVOT 行转列实战:从静态到动态列与性能优化 2026/9/25 19:25:30

SQL Server PIVOT 行转列实战:从静态到动态列与性能优化

简介:这份PDF资料聚焦SQL Server中行转列的核心技术PIVOT,面向需要处理报表数据转换的数据库开发人员与SQL学习者。内容以WEEK_INCOME收入表为例,从传统CASE加SUM写法切入,逐步讲解PIVOT操作符的语法结构、聚合函数选择、FOR子句的…

阅读更多 →
IMS 503故障快速定位:代理到AS的TCP/TLS连通性排查 2026/9/25 19:25:23

IMS 503故障快速定位:代理到AS的TCP/TLS连通性排查

简介:本资源是一份聚焦5G网络优化实战的典型VoLTE故障分析案例,面向通信工程技术人员、网优工程师及5G/4G无线网络运维人员,重点解决IMS域返回503 Service Unavailable导致用户强制回落至4G的核心问题。文档深入剖析了media bearer lost根因—…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉