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

C++三大隐藏坑:初始化列表、隐式转换、static成员你真的用对了吗?

📅 2026 · C++ 系列笔记C++面向对象构造函数

目录

1. 再探构造函数——初始化列表

哪些成员必须用初始化列表?

C++11 成员变量缺省值

2. 类型转换与 explicit

3. static 静态成员


1. 再探构造函数——初始化列表

之前写构造函数时,我习惯在函数体内用赋值语句初始化成员变量。但 C++ 其实提供了另一种更正规的方式:初始化列表。它以冒号:开头,紧跟在参数列表之后。

C++

class Date { public: Date(int year, int month, int day) : _year(year) // 初始化列表 , _month(month) , _day(day) {} private: int _year; int _month; int _day; };

哪些成员必须用初始化列表?

  • 引用成员变量int& _ref):引用必须在定义时初始化
  • const 成员变量const int _n):常量不能赋值,只能初始化
  • 没有默认构造函数的类类型成员:编译器不知道怎么"默认构造"它

⚠️ 初始化列表中成员的初始化顺序,由它们在类中声明的顺序决定,与初始化列表里写的顺序无关!建议两者保持一致,避免踩坑。

C++(必须走初始化列表的示例)

class Time { public: Time(int hour) : _hour(hour) {} // 无默认构造 private: int _hour; }; class Date { public: Date(int& x, int year = 1, int month = 1, int day = 1) : _year(year) , _month(month) , _day(day) , _t(12) // 必须在这里给 Time 传参 , _ref(x) // 引用必须在初始化列表 , _n(1) // const 必须在初始化列表 {} private: int _year, _month, _day; Time _t; // 无默认构造 int& _ref; // 引用 const int _n; // const };

C++11 成员变量缺省值

C++11 支持在成员声明处给缺省值,这个缺省值是给初始化列表"兜底"用的——如果初始化列表没有显式初始化该成员,就用这个缺省值。

class Date { public: Date() : _month(2) {} // 只覆盖 _month,其余用缺省值 private: int _year = 1; // 缺省值 int _month = 1; int _day; // 无缺省值,初始化未定义 Time _t = 1; const int _n = 1; };

🧩 经典考题:下面程序输出什么?

C++

class A { public: A(int a) : _a1(a) , _a2(_a1) // ⚠️ 初始化顺序由声明顺序决定! {} void Print() { cout << _a1 << " " << _a2; } private: int _a2 = 2; // 声明在前,先初始化 int _a1 = 2; // 声明在后,后初始化 };

A. 1 1B. 2 2C. 编译报错F. 1 随机值


2. 类型转换与 explicit

C++ 允许内置类型通过对应的构造函数隐式转换为类对象,这个特性有时很方便,但也容易让代码语义不清晰。

C++ class A { public: A(int a1) : _a1(a1) {} A(int a1, int a2) : _a1(a1), _a2(a2) {} private: int _a1 = 1; int _a2 = 2; }; // 单参数隐式转换(构造一个临时对象,编译器优化为直接构造) A aa1 = 1; const A& aa2 = 1; // 合法,const 引用延长临时对象生命周期 // C++11 支持多参数隐式转换 A aa3 = {2, 2};

💡 在构造函数前加explicit可禁止隐式类型转换,让代码意图更明确。推荐对单参数构造函数加explicit,避免意外转换。


3. static 静态成员

static 成员分为静态成员变量和静态成员函数,两者都属于整个类,而不属于某个具体对象。

  • 静态成员变量存放在静态区,所有对象共享同一份
  • 静态成员变量必须在类外定义初始化(不能在声明处给缺省值,因为它不走构造函数)
  • 静态成员函数没有 this 指针,因此只能访问静态成员
  • 访问方式:类名::静态成员对象.静态成员(仍受访问限定符限制)

C++(统计存活对象数量)

class A { public: A() { ++_scount; } A(const A& t) { ++_scount; } ~A() { --_scount; } static int GetACount() { return _scount; } private: static int _scount; // 类内声明 }; int A::_scount = 0; // 类外初始化 int main() { cout << A::GetACount() << endl; // 0 A a1, a2; A a3(a1); cout << A::GetACount() << endl; // 3 return 0; }

✅ 经典应用:利用 static 成员实现"计算程序中创建了多少个对象"、"求 1+2+…+n(变长数组技巧)"等。


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

相关文章:

  • 光伏MPPT中粒子群算法与PO扰动结合的优化方法:加入终止条件与重启功能
  • Janus-Pro-7B多场景落地:食品包装图→营养成分识别+健康建议生成
  • 如何快速掌握LaserGRBL:开源激光雕刻软件的终极入门指南
  • 别再只测RCE了!手把手教你复现Aria2任意文件写入漏洞(附Docker靶场搭建)
  • 华盛锂电冲刺港股:年营收8.7亿,亏256万 沈锦良父子控制58%股权
  • Rusted PackFile Manager:5分钟上手,打造你的全面战争专属模组
  • AUTOSAR通信栈实战指南 - 从DBC到模块联调,打通CAN信号流配置全链路
  • 揭秘LLM+符号执行融合架构:2026奇点大会上验证的AI根因分析准确率达94.7%
  • XUnity.AutoTranslator终极指南:5分钟实现Unity游戏AI实时翻译
  • 次元画室新手入门:不懂绘画也能设计二次元角色的秘诀
  • Umi-OCR完全指南:免费开源离线OCR软件的7大应用场景揭秘
  • 用GEE和Sentinel-5P数据,5分钟搞定城市空气质量变化趋势分析(以NO2、O3为例)
  • 大模型修炼秘籍 第十四章:安全护体——红队测试与防御
  • 2篇2章1节:医药类SCI论文的难度和常规投稿流程
  • 基于MATLAB的模糊逻辑交叉口红绿灯控制系统技术解析
  • D2DX终极指南:让暗黑破坏神2在现代PC上焕发新生的完整教程
  • 深度学习在自然语言处理中的应用
  • 一天一个开源项目(第76篇):Cangjie Skill —— 将书本知识炼金为 AI 智能体可执行的技能
  • C语言、C++和C#:三大编程语言核心差异详解
  • Abel逆变换在等离子体诊断中的应用:如何用Python处理轴对称光谱数据
  • 如何轻松设计你的动物森友会岛屿:Happy Island Designer 完整指南
  • 机顶盒ADB调试工具大全|多品牌型号一键开启ADB(Win10/11专用)
  • 次元画室Windows安装详解:从Git克隆到Web界面启动全流程
  • [NEW]六边形框架升级!轮动策略增加阶梯止盈止损!股票量化分析工具QTYX-V3.4.5
  • 2026年3月定制化酒店全案设计公司哪家好,网红民宿/工业风民宿/民宿全案设计/侘寂民宿,酒店全案设计策划多少钱 - 品牌推荐师
  • 别再死记MobileNetV2结构了!从‘倒残差’设计思想理解它为何又快又好
  • 云原生应用开发实践
  • CMake实战:从语法解析到工程构建
  • LAMMPS in文件范例
  • 低功耗入门级原创SAR ADC电路设计成品,smic 0.18工艺,适合初学者研习 包含电路设...