NSDMI是C++11引入的特性,允许在类内直接为非静态数据成员指定默认初始值,使用=或{}语法,不支持圆括号初始化;它作为兜底默认值,在构造函数未显式初始化时生效,支持内置及可访问构造函数的类类型,但不支持static、const(非inline)和引用成员。

非静态数据成员初始化(NSDMI,Non-Static Data Member Initialization)是 C++11 引入的语法特性,允许在类定义内部直接为非静态数据成员指定默认初始值,无需等到构造函数体中或成员初始化列表里。
NSDMI 的基本语法
直接在成员声明后使用 = 或 {} 初始化:
- int x = 42;
- std::string name{"default"};
- std::vector
data{1, 2, 3};
注意:不能用圆括号初始化(如 int y(10);),这会被误解析为函数声明(最 vexing parse 问题)。
NSDMI 和构造函数的关系
NSDMI 提供的是“兜底默认值”,当构造函数未在初始化列表中显式初始化该成员时,才生效:
立即学习“C++免费学习笔记(深入)”;
- 若构造函数初始化列表中写了
Member(value),NSDMI 被忽略; - 若初始化列表中没提该成员,且构造函数体为空或未赋值,则自动应用 NSDMI;
- 即使构造函数体中写了
member = ...;,NSDMI 仍会在进入构造函数体前先执行(即先初始化、再赋值,可能带来额外开销)。
适用类型和限制
NSDMI 支持所有可默认构造或可拷贝/移动初始化的类型,包括自定义类(只要其构造函数可访问):
- 内置类型(
int,double等)可直接赋值; - 类类型需有可访问的构造函数(如 public 默认构造函数或匹配的初始化列表构造函数);
- static 成员、const 成员(除非同时是 inline)、引用成员不支持 NSDMI(引用必须在初始化列表中绑定);
- NSDMI 表达式中不能引用
this、其他成员或未声明的成员(顺序依赖:只能用前面已声明的成员)。
实际意义和好处
NSDMI 减少重复代码,提升可维护性:
- 多个构造函数共享同一默认值时,不用在每个初始化列表里重复写;
- 避免遗漏初始化导致未定义行为(尤其对内置类型);
- 配合委托构造函数,让逻辑更清晰;
- 使类定义更自文档化——默认值一目了然。
基本上就这些。它不复杂但容易忽略细节,用对了能写出更干净、更安全的类。









