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

C++初阶之类和对象》【初始化列表 + 自定义类型转换 + static成员】

什么是初始化列表?

初始化列表(Initializer List):是 C++ 中用于在对象构造时直接初始化成员变量的语法。

  • 它位于构造函数的参数列表之后,函数体之前,以冒号:开始,后面跟着用逗号分隔的成员变量初始化列表。
  • 它核心作用是在对象内存分配完成后立即初始化成员,而非先默认初始化再赋值。

代码语言:javascript

AI代码解释

class MyClass { int _a; double _b; std::string _s; public: // 初始化列表语法 MyClass(int a, double b, const std::string& s) : _a(a), _b(b), _s(s) // 初始化列表 { // 构造函数体(此时成员已初始化) } };
为什么要使用初始化列表?

使用初始化列表主要有以下两点原因:

  1. 为了提高类的成员变量的初始化效率
  2. 有些成员变量不得不使用初始化列表进行初始化

--------------------为了提高效率--------------------

对于类类型的成员变量 :

  • 如果没有使用初始化列表,在进入构造函数体之前,会先调用成员变量的默认构造函数进行初始化,然后在构造函数体中再进行赋值操作,这会产生额外的开销。
  • 而使用初始化列表,可以直接调用成员变量的合适构造函数进行初始化,避免了先默认构造再赋值的过程,从而提高了初始化效率。
    • 例如:当成员变量是string类型时,使用初始化列表可以直接调用string的构造函数来初始化,而不是先默认构造一个空字符串,再进行赋值。

代码语言:javascript

AI代码解释

class Student { string _name; public: // 低效写法:先默认构造空字符串,再赋值 Student(const std::string& name) { _name = name; } // 高效写法:直接调用string的拷贝构造 Student(const string& name) : _name(name) {} };

--------------------不得不使用--------------------

初始化 const 成员和引用成员

  • const成员变量和引用成员在定义后就不能被修改,因此必须在定义时进行初始化。
  • 初始化列表是在构造函数中初始化const成员和引用成员的唯一方法。如果不使用初始化列表,试图在构造函数体中对const成员或引用成员进行赋值,将会导致编译错误。

代码语言:javascript

AI代码解释

----------------------------初始化 const 成员---------------------------- class ConstDemo { const int _value; public: ConstDemo(int v) : _value(v) {} // 必须用初始化列表 }; ----------------------------初始化 const 成员---------------------------- class RefDemo { int& _ref; public: RefDemo(int& r) : _ref(r) {} // 必须用初始化列表 };

调用无默认构造的成员

  • 当成员变量的类没有默认构造函数,只有带参数的构造函数时,必须使用初始化列表来传递参数进行初始化。
  • 否则,编译器无法找到合适的构造函数来初始化成员变量,从而引发编译错误。

代码语言:javascript

AI代码解释

class Engine { public: Engine(int power) {} // 只有带参构造 }; class Car { Engine _engine; public: Car() : _engine(100) {} // 必须显式初始化 };
怎么使用初始化列表?

代码语言:javascript

AI代码解释

#include<iostream> using namespace std; // Time类定义 class Time { public: /*---------------Time类的构造函数(带参数)---------------*/ // 注意:这个类没有提供默认构造函数(无参构造函数) Time(int hour) :_hour(hour) { cout << "Time类的构造函数Time()" << endl; } private: int _hour; }; // Date类定义 class Date { public: /*---------------Date类的构造函数---------------*/ Date(int& x, int year = 1, int month = 1, int day = 1) :_year(year) // 初始化_year , _month(month) // 初始化_month , _day(day) // 初始化_day , _t(12) // 初始化Time类成员(必须提供参数) , _ref(x) // 初始化引用成员(必须通过初始化列表) , _n(1) // 初始化const成员(必须通过初始化列表) { // 如果尝试在构造函数体内初始化以下成员,会导致编译错误: // 1. _t(12) - 错误:Time类没有默认构造函数 // 2. _ref = x - 错误:引用必须在初始化列表中初始化 // 3. _n = 1 - 错误:const成员必须在初始化列表中初始化 } /*---------------打印日期信息---------------*/ void Print() const { cout << _year << "-" << _month << "-" << _day << endl; //const成员函数,保证不会修改对象状态 } private: int _year; int _month; int _day; Time _t; // Time类成员(没有默认构造函数) int& _ref; // 引用成员 (必须在初始化列表中初始化) const int _n; // const成员 (必须在初始化列表中初始化) }; int main() { int i = 0; //定义一个整型变量用于初始化Date的引用成员 // 创建Date对象d1 // 参数: // i - 用于初始化_ref引用成员 // 其他参数使用默认值 Date d1(i); // 调用Print方法输出日期信息 d1.Print(); return 0; } /* * 关键点总结: * 1. 初始化列表的必要性: * - 必须用于初始化:引用成员(_ref)、const成员(_n)、没有默认构造函数的类成员(_t) * * 2. 初始化顺序: * - 成员变量的初始化顺序由它们在类中的声明顺序决定(_year→_month→_day→_t→_ref→_n) * - 与初始化列表中的书写顺序无关 * * 3. 特殊成员初始化: * - 引用和const成员:只能在初始化列表中初始化 * - 没有默认构造的类成员:必须在初始化列表中显式构造 * * 4. 良好实践: * - 即使对普通成员变量(如:_year)也使用初始化列表 * - 保持初始化列表顺序与成员声明顺序一致 */

在这里插入图片描述

初始化列表 vs 构造函数体内赋值谁能获胜?

特性

初始化列表

构造函数内赋值

const成员

✔️ 支持

❌ 编译错误

引用成员

✔️ 支持

❌ 编译错误

无默认构造的成员

✔️ 支持

❌ 编译错误

性能

更高效(直接构造)

可能低效(先默认构造再赋值)

初始化顺序

由成员声明顺序决定

无顺序依赖

使用初始化列表的注意事项有哪些?

在 C++ 中,成员变量的初始化遵循两大规则:


其一:初始化顺序仅取决于变量在类中声明的先后次序,与初始化列表中的排列顺序无关。


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

相关文章:

  • 2026年热门上线即送神装的传奇网页游戏精选
  • 基于S7 - 200 PLC和组态王小区变频恒压供水控制系统设计
  • 2026工业废气治理设备厂家+中水回用水处理系统厂家+一体化污水处理设备厂家-石家庄天旺环保科技领衔 - 栗子测评
  • Claude 5天重写老库引全网争议,维护者擅自更换开源协议,退网15年原作者突然现身:不准改!
  • 《C++初阶之类和对象》【友元 + 内部类 + 匿名对象】
  • 当变频器遇上S7-200:一个水厂老司机的自白
  • 基于CW32F030C8T6的BMP180气压传感器I2C驱动移植与海拔测量实战
  • 《C++初阶之STL》【auto关键字 + 范围for循环 + 迭代器】
  • 2026年混凝土外加剂实力厂家甄选指南与TOP5推荐 - 2026年企业推荐榜
  • 八皇后(dfs 模版
  • YOLOv5+GraspNet实战:如何用Python快速搭建机械臂抓取系统(附完整代码)
  • ESP32S3基础2-多任务处理、EXTI中断、时钟与定时器
  • MySQL【表的约束下】
  • 手把手教你用阿里云镜像制作glibc.i686离线安装包(CentOS7专属)
  • [特殊字符] Nano-Banana实战案例:从手机到家电,全品类产品拆解图生成实录
  • Zotero7文献笔记模版:从安装到自定义的完整指南
  • 喜讯!第十六批生成合成类算法备案备案号公布
  • 天梯赛编程题 L2—048 寻宝图 题解
  • 软件安全实战指南:从零日漏洞到安全部署的核心要义
  • Visual Studio误删.vcxproj.filters文件?3步教你手动重建(附模板)
  • Unity URP渲染管线进阶---自定义RendererFeature实战解析
  • 阿姆智创21.5寸嵌入式工控一体机,多场景智造的嵌入式终端,源头工厂ODM定制应用
  • 衡山派D133EBS开发板驱动MS1100 VOC气体传感器实战指南
  • Linux用户必备:5款免费CAD软件实测对比(附安装指南)
  • OpenMV实战指南:sensor与image模块的高效配置与图像处理技巧
  • 从SCAU综合实验到实战:C语言文件操作与字符处理的进阶解析
  • 避坑指南:PyQt5+Matplotlib动态绘图卡顿?试试这3种优化方案
  • PyTorch量化实战:从模型压缩到移动端部署
  • ENVI遥感图像处理入门实战:从数据加载到基础分析
  • 告别WebSecurityConfigurerAdapter:Spring Security 5.7+组件化配置实战