导读:本期聚焦于小伙伴创作的《C++中的非静态数据成员初始化(NSDMI)是什么?C++11类内初始化语法怎么用?》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C++中的非静态数据成员初始化(NSDMI)是什么?C++11类内初始化语法怎么用?》有用,将其分享出去将是对创作者最好的鼓励。

非静态数据成员初始化(NSDMI)是C++11标准引入的重要特性,指的是在类的定义内部直接为非静态数据成员指定初始值的能力,也被叫做类内初始化。在C++11之前,非静态数据成员只能在构造函数的初始化列表或者构造函数体内完成初始化,类定义中不能直接给成员赋值,这个限制让很多类的初始化代码变得冗余。

C++中的非静态数据成员初始化(NSDMI)是什么?C++11类内初始化语法怎么用?

NSDMI的基本语法

使用NSDMI的语法非常简单,只需要在类定义中声明非静态数据成员时,在成员后面加上等号或者花括号初始化器即可,不需要额外的关键字。需要注意的是,只有非静态数据成员可以使用这个特性,静态数据成员依然需要遵循之前的初始化规则。

下面是基础的语法示例:

#include <iostream>
#include <string>

class User {
public:
    // 非静态数据成员类内初始化,使用等号初始化
    int id = 1001;
    // 使用花括号初始化
    std::string name{"默认用户"};
    // 内置类型也可以用花括号初始化
    double score{0.0};
};

int main() {
    User u;
    std::cout << "id: " << u.id << std::endl;
    std::cout << "name: " << u.name << std::endl;
    std::cout << "score: " << u.score << std::endl;
    return 0;
}

初始化优先级规则

当类中同时存在NSDMI和构造函数的初始化列表时,会遵循固定的优先级规则:构造函数的初始化列表优先级高于类内初始化。也就是说,如果构造函数的初始化列表对该成员进行了初始化,那么类内指定的初始值会被忽略,直接使用初始化列表的值;如果构造函数的初始化列表没有覆盖该成员,才会使用类内初始值。

我们可以通过下面的代码验证这个规则:

#include <iostream>
#include <string>

class Product {
public:
    // 类内初始值
    std::string name{"未知商品"};
    double price = 0.0;
    int stock{10};

    // 构造函数1:初始化列表覆盖部分成员
    Product(const std::string& n, double p) : name(n), price(p) {
        // 这里stock没有在初始化列表中出现,会使用类内的初始值10
    }

    // 构造函数2:初始化列表覆盖所有成员
    Product(const std::string& n, double p, int s) : name(n), price(p), stock(s) {
        // 所有成员都使用初始化列表的值,类内初始值被忽略
    }
};

int main() {
    Product p1("手机", 2999.0);
    std::cout << "p1 name: " << p1.name << ", price: " << p1.price << ", stock: " << p1.stock << std::endl;

    Product p2("电脑", 5999.0, 20);
    std::cout << "p2 name: " << p2.name << ", price: " << p2.price << ", stock: " << p2.stock << std::endl;
    return 0;
}

NSDMI的使用限制

虽然NSDMI带来了很多便利,但是也有一些使用限制需要开发者注意:

  • 只能用于非静态数据成员,静态数据成员不能使用类内初始化,依然需要在类外定义并初始化。
  • 类内初始化的表达式不能是this指针,因为成员初始化时对象还没有完全构造完成,this指针还不可用。
  • 初始值不能是正在构造的类的对象,比如类A的成员不能用A的实例来初始化,会导致递归初始化问题。
  • 对于数组类型的非静态成员,类内初始化只能使用花括号初始化器,不能使用等号初始化。

NSDMI的优势

相比C++11之前的方式,NSDMI主要有几个明显的优势:

减少重复代码:如果多个构造函数都需要对同一个成员设置相同的初始值,之前需要在每个构造函数的初始化列表都写一遍,现在只需要在类内写一次即可。
避免遗漏初始化:如果新增了非静态数据成员,忘记在构造函数初始化列表中添加,就会导致成员未初始化,使用NSDMI可以给成员一个默认的合理初始值,降低出错概率。
提升代码可读性:成员初始值和成员声明放在一起,开发者看类定义的时候就能直接知道成员的默认取值,不需要跳转到构造函数查看初始化逻辑。

常见使用场景

NSDMI适合用在以下场景:

  • 类的非静态数据成员有通用的默认取值,大部分情况下不需要修改。
  • 类有多个构造函数,多个构造函数都需要对同一个成员设置相同的初始值。
  • 需要给成员一个安全的默认初始值,避免未初始化导致的未定义行为。

需要注意的是,如果成员的初始值依赖构造函数的参数,那么还是需要在构造函数的初始化列表中完成初始化,NSDMI更适合设置固定的默认初始值。

C++11非静态数据成员初始化NSDMI类内初始化修改时间:2026-07-04 00:21:30

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。