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

【C++11新章】列表初始化详解


🌈个人主页:聆风吟_
🔥系列专栏:C++11新章
🔖少年有梦不应止于心动,更要付诸行动。


文章目录

  • 一、背景:C++98传统的 {}
  • 二、什么是列表初始化?
  • 三、基础用法示例
    • 3.1 基础变量初始化
    • 3.2 数组初始化
    • 3.3 动态分配内存
  • 四、进阶用法示例
    • 4.1 结构体初始化
    • 4.2 类初始化
    • 4.3 STL 容器初始化
  • 六、列表初始化的 4 大好处
  • 📝全文总结

一、背景:C++98传统的 {}

C++98中一般数组和结构体可以用{}进行初始化。

#include<iostream>usingnamespacestd;structPoint{int_x;int_y;};intmain(){// 变量:=intx=10;// 数组:{}intarray1[]={1,2,3,4,5};intarray2[5]={0};// 结构体:{}Point p={1,2};return0;}


二、什么是列表初始化?

在 C++11 之前,初始化方式特别乱:

  • 变量用=

  • 数组用{}

  • 对象用()

  • 容器没法直接批量赋值

C++11 直接统一:不管什么类型,全都能用{}初始化,这就叫列表初始化

语法格式(两种写法完全等价,都可以用):

类型 变量名{1,2,...};// 推荐写法类型 变量名={1,2,...};

📌小贴士:{}初始化过程中可以省略=



三、基础用法示例

3.1 基础变量初始化

内置类型(int、double、bool 等)直接用{}赋值,语法更统一。

#include<iostream>usingnamespacestd;intmain(){// C++98 传统写法inta=10;doubleb=3.14;// C++11 列表初始化intc{10};// 等价 int c = 10;doubled{3.14};// 等价 double d = 3.14;boole{true};// 等价 bool e = true;cout<<"c = "<<c<<endl;cout<<"d = "<<d<<endl;cout<<"e = "<<e<<endl;return0;}

输出结果:

c = 10 d = 3.14 e = 1

3.2 数组初始化

#include<iostream>usingnamespacestd;intmain(){// C++98intarr1[3]={1,2,3};// C++11 列表初始化(两种写法等价)intarr2[3]={1,2,3};intarr3[]{1,2,3};// 自动推导长度为3intarr4[5]{1,2,3};// 未赋值元素自动初始化为0return0;}

3.3 动态分配内存

C++11 支持用{}初始化动态分配的对象:

#include<iostream>usingnamespacestd;classPerson{public:Person(inta,string n):age(a),name(n){}private:intage;string name;};intmain(){// 动态int数组,初始化为{1,2,3}int*arr=newint[3]{1,2,3};// 动态对象初始化Person*p=newPerson{25,"王五"};return0;}


四、进阶用法示例

4.1 结构体初始化

#include<iostream>usingnamespacestd;structPoint{intx;inty;intz;};intmain(){// 列表初始化结构体// 1. 完整初始化(给所有成员赋值)Point d1={2026,1,1};// 传统写法Point d2{2026,1,1};// C++11 简写(推荐)// 2. 部分初始化(没写的自动 = 0)Point d3{2026};// year=2026, month=0, day=0Point d4{2026,1};// year=2026, month=1, day=0// 3. 零初始化(全部 = 0)Point d5{};// year=0, month=0, day=0return0;}

4.2 类初始化

列表初始化会自动调用匹配的构造函数

#include<iostream>#include<vector>usingnamespacestd;classDate{public:Date(intyear=1,intmonth=1,intday=1):_year(year),_month(month),_day(day){cout<<"Date(int year, int month, int day) ——> 构造函数"<<endl;}Date(constDate&d):_year(d._year),_month(d._month),_day(d._day){cout<<"Date(const Date& d) ——> 拷贝构造函数"<<endl;}private:int_year;int_month;int_day;};

(1)C++98 传统初始化

// 传统圆括号初始化:直接调用构造函数intmain(){Dated0(2025,1,1);return0;}

输出:

Date(int year, int month, int day) ——> 构造函数

(2)C++11 列表初始化

// 写法1:赋值形式的列表初始化// 理论:{2026,1,1} → 构造临时对象 → 拷贝构造d1// 编译器优化:直接构造d1,不会调用拷贝构造Date d1={2026,1,1};// 写法2:直接列表初始化(推荐)// 最简洁,直接调用构造函数Date d2{2026,1,1};

输出:

Date(intyear,intmonth,intday)——>构造函数Date(intyear,intmonth,intday)——>构造函数

(3)隐式类型转换

intmain(){// 因为构造是全缺省,1个参数也能匹配Date d3={2025};// 列表初始化Date d4=2025;// C++98 隐式类型转换return0;}

输出:

Date(intyear,intmonth,intday)——>构造函数Date(intyear,intmonth,intday)——>构造函数

(4)使用场景

intmain(){vector<Date>v;// 写法1:隐式转换构造v.push_back(2026);// 写法2:列表初始化构造(最常用)v.push_back({2026,1,1});// 错误写法:// v.push_back(2026, 1, 1); // 报错!push_back 只能传1个参数return0;}

讲解:

  1. push_back(2026):2026 隐式转换成 Date 对象,先构造,再拷贝进容器

  2. push_back({2026,1,1}){2026,1,1}直接构造 Date 临时对象,再拷贝进容器

  3. 为什么不能写push_back (2026,1,1)

    • push_back 只能接收1 个参数

    • 三个 int 是 3 个参数,语法错误

    • 必须用{}打包成一个对象才能传入

输出:

Date(intyear,intmonth,intday)——>构造函数Date(constDate&d)——>拷贝构造函数Date(intyear,intmonth,intday)——>构造函数Date(constDate&d)——>拷贝构造函数

4.3 STL 容器初始化

这是 C++11 最爽的地方,vector、map、string 等容器都能直接赋值

#include<iostream>#include<vector>#include<map>#include<string>usingnamespacestd;intmain(){// vector 直接批量赋值vector<int>v{1,2,3,4,5};// string 初始化string s{"hello world"};// map 键值对直接初始化map<int,string>mp{{1,"one"},{2,"two"}};return0;}


六、列表初始化的 4 大好处

(1)统一所有初始化写法

不管是基础变量、数组、结构体、类、STL容器全部只用{}一种写法,彻底告别=(){}混用的混乱规则。

#include<vector>#include<string>// 旧版 C++:初始化语法五花八门,极易记混inta=10;// 等号intarr[]={1,2,3};// 数组std::vector<int>v(2,5);// 构造函数()structPoint{intx,y;};Point p={1,2};// 结构体// 现代 C++:全部统一用 {},一套规则走天下inta{10};// 变量intarr[]{1,2,3};// 数组std::vector<int>v{2,5};// 容器Point p{1,2};// 结构体std::string s{"hello"};// 字符串

总结:列表初始化{}语法,统一所有类型初始化,代码风格更整洁,学习/记忆成本大幅降低。


(2)防止「窄化转换」,编译期拦截类型风险

禁止不安全的隐式缩窄转换(比如double → intlong → short),编译器直接报错,从根源避免数值丢失、精度错误。

📌小贴士

窄化转换:把大范围类型偷偷转成小范围(比如 double → int,long → char)。

// 1. 传统初始化:隐式缩窄转换,编译器不报错(埋坑!)doublepi=3.1415;intx=pi;// 合法!double 偷偷转 int,精度丢失charc=1000;// 合法!数值溢出,结果不可预期// 2. 列表初始化:严格禁止缩窄转换,直接编译报错(安全!)intx{pi};// 报错:无法从 double 缩窄为 intcharc{1000};// 报错:1000 超出 char 范围floatf{1.2345};// 报错:double 不能缩窄为 float

总结:列表初始化 = 类型安全防火墙,所有不安全的隐式类型转换,都会在编译期被拦截,程序更健壮。


(3)容器直接批量赋值,告别繁琐 push_back

vector/map/list等所有 STL 容器,直接用{}批量初始化/赋值,一行代码替代 N 行push_back,代码极简直观。

#include<vector>#include<map>#include<iostream>// 旧版:反复 push_back,代码冗长std::vector<int>v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);// 列表初始化:一行搞定,清晰优雅std::vector<int>v2{1,2,3,4};// map 同样支持,键值对直接批量写std::map<std::string,int>score{{"张三",90},{"李四",85},{"王五",95}};

总结:批量初始化容器,代码量锐减 80%,可读性、维护性直接拉满。


(4)空列表{}默认初始化,杜绝野值

对任意类型使用{}编译器会自动执行「值初始化」

  • 基础类型(int/double/指针)→ 自动清零

  • 自定义类型 → 调用默认构造

彻底杜绝未初始化变量导致的野值、崩溃、随机bug

// 1. 传统定义:不初始化 = 随机野值(高危!)inta;// 未初始化,值是内存垃圾(随机数)doubled;// 随机垃圾值int*ptr;// 野指针,访问直接崩溃// 2. 空列表 {}:强制默认初始化,全部安全清零inta{};// = 0doubled{};// = 0.0int*ptr{};// = nullptr(空指针,安全)std::vector<int>v{};// 空容器// 结构体/类同样适用structPoint{intx,y;};Point p{};// x=0, y=0

总结:{}= 安全初始化兜底,再也不用担心忘记赋值导致的诡异bug。



📝全文总结

C++11列表初始化({}是对C++98繁杂初始化语法的大一统升级,它用一套极简、安全、统一的规则,彻底解决了传统初始化方式混乱、易错、不安全的痛点,是现代C++开发中首选、推荐、必备的初始化方式。它的核心价值可以浓缩为4句话:

  1. 语法大一统基础变量、数组、结构体、类对象、STL容器,所有类型统一用{}初始化,代码风格极致简洁统一;
  2. 类型更安全:编译期严格禁止窄化转换(如double转int、大数转char),从源头拦截类型溢出、精度丢失的风险;
  3. 编码更高效:STL容器(vector/map/list等)支持直接批量赋值,一行代码替代多行push_back,大幅简化容器初始化;
  4. 使用更稳健:空列表{}会自动对所有类型执行值初始化(基础类型清零、指针置nullptr、自定义类型调默认构造),彻底杜绝野值、野指针导致的程序bug。

简单来说:现代C++开发,初始化就用{},简洁、安全、不出错!

今天的干货分享到这里就结束啦!如果觉得文章还可以的话,希望能给个三连支持一下,聆风吟的主页还有很多有趣的文章,欢迎小伙伴们前去点评,您的支持就是作者前进的最大动力!

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

相关文章:

  • 2026年合肥3+2学校推荐工作:趋势洞察与优质选择 - 2026年企业资讯
  • 2026年压力变送器厂家推荐:智能高精度/扩散硅/电容式/远传/防爆型压力变送器品牌与选型指南 - 品牌企业推荐师(官方)
  • 通辽自建房装修技术解析:通辽装修工作室/通辽装饰/通辽专业的装修/通辽精装修/通辽靠谱装修/通辽二手房翻新/选择指南 - 优质品牌商家
  • 硬件分拣系统(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码
  • 如何判断 SFT 到什么程度就可以开始做 RL
  • 模型单机多卡训练笔记
  • 2026年更新:深度解析非标无动力游乐设备实力厂家的选择之道 - 2026年企业资讯
  • 2025年09月 GESP等级认证C++编程(一级)试题解析
  • 别再为多重共线性发愁了!用Python的sklearn快速上手岭回归实战
  • 2022年软考-公司人事管理—软件设计师—东方仙盟
  • 2026年当下,如何选择一家靠谱的烘焙烤箱销售厂家?这份业内推荐请收好 - 2026年企业资讯
  • 瑞德克斯信息服务平台节奏易懂吗?
  • 实打实口碑!2026年6月上海松江区靠谱银元回收+老银锭回收店铺推荐 - 沪上贵金属口碑推荐官
  • 2026年 松下万宝压缩机厂家推荐:高效节能/稳定耐用的空调与冷柜压缩机优选品牌解析 - 品牌企业推荐师(官方)
  • SPI驱动开发实战:轮询、中断与DMA模式详解与性能优化
  • 2026年Q2非晶带焊料评测:银焊膏、锡焊膏、锡青铜焊膏、镍焊膏、阻流剂、预制成型件、颗粒焊料、黄铜焊膏、定制焊料选择指南 - 优质品牌商家
  • 黑客必备的一体化黑客工具
  • TMS320F280049C ADC实战:从ePWM触发到多通道采样,一个电机控制工程师的配置笔记
  • Solidity Gas 优化底座:从 EVM 字节码、Opcode 内存布局到 Yul 汇编底层压榨算力实战
  • 后端 API 设计:RESTful 与 GraphQL 的架构权衡与实战选择
  • 别再纠结了!手把手教你为STM32项目挑选最合适的调试器(J-Link/ST-Link/CMSIS-DAP对比)
  • 银行级机器学习系统:从模型上线到生产就绪的工程实践
  • 国内预制成型钎焊制品供应商综合实力排行盘点:金基焊料/钛基焊料/钯基焊料/铝焊膏/银焊膏/锡焊膏/锡青铜焊膏/镍焊膏/选择指南 - 优质品牌商家
  • 2026年 重锤料位计厂家推荐:精准测量/抗粉尘/耐高温,工业物位监测优质品牌深度解析 - 品牌企业推荐师(官方)
  • CSDN AI数字营销权限体系深度拆解(含官方未公开的L4-L6高阶权限清单)
  • 2026年通辽市名气TOP5装饰公司客观盘点:通辽靠谱装修/通辽二手房翻新/通辽别墅装修/通辽大宅装修/通辽大平层装修/选择指南 - 优质品牌商家
  • 导入模板下载
  • 别再为多重共线性头疼了!用sklearn的RidgeCV和Lasso搞定你的回归模型(附Longley数据集实战)
  • 微软董事霍夫曼将不参与连任竞选,欲专注人工智能药物研发初创公司
  • 2026年FY不锈钢液下泵权威品牌TOP5盘点:耐腐泵/耐腐耐磨液下泵/耐腐耐磨砂浆泵/耐腐耐腐循环泵/耐腐蚀离心泵/选择指南 - 优质品牌商家