C++成员变量的初始化顺序由它们在类中的声明顺序决定,而不是初始化列表中的顺序

1. 代码结构分析

cpp 复制代码
class Test
{
public:
    Test(int data=100) : mb(data), ma(mb) {}
    void show() { cout << "ma:" << ma << " mb:" << mb << endl; }
private:
    int ma;
    int mb;
};

int main()
{
    Test t1;
    t1.show();
    return 0;
}
  • 类定义Test 类包含两个私有成员 mamb,以及一个带默认参数的构造函数和一个打印函数。
  • 构造函数 :使用了初始化列表,看起来是先初始化 mb,再用 mb 初始化 ma
  • 主函数 :创建了一个 Test 对象 t1,并调用 show() 打印成员变量。

2. 关键问题:初始化顺序

在C++中,成员变量的初始化顺序由它们在类中的声明顺序决定,而不是初始化列表中的顺序

  • 在类的声明中,int ma; 出现在 int mb; 之前。
  • 因此,构造函数初始化列表的实际执行顺序是:
    1. 先初始化 ma,使用的是 mb 的值,但此时 mb 还未被初始化,是一个随机的垃圾值。
    2. 然后初始化 mb,将其赋值为 data(即100)。

3. 运行结果

当执行 t1.show() 时,输出结果是未定义的:

  • mb 的值是确定的,为 100
  • ma 的值是未定义的,它是在 mb 初始化之前就被赋值的垃圾值,无效值,-958993460,0xcc

4. 正确的写法

为了避免这种问题,应该确保初始化列表的顺序与成员声明顺序一致,或者避免在初始化一个成员时使用另一个未初始化的成员。

cpp 复制代码
class Test
{
public:
    // 修正:先初始化mb,再用mb初始化ma,同时保证声明顺序一致
    Test(int data=100) : mb(data), ma(mb) {} 
private:
    int mb; // 调整声明顺序,先声明mb
    int ma;
};

或者更稳妥地直接使用参数初始化:

cpp 复制代码
Test(int data=100) : ma(data), mb(data) {}

总结

这段代码的核心问题在于成员变量的初始化顺序与初始化列表顺序不一致 ,导致 ma 被初始化为一个未定义的值。这是C++中一个常见的陷阱,需要特别注意。

相关推荐
代钦塔拉27 分钟前
Qt4 vs Qt5 带参数信号槽的连接方式详解
开发语言·数据库·qt
InfinteJustice2 小时前
踩坑分享C 语言文件操作全攻略:从基础读写到随机访问与缓冲区原理
c语言·开发语言·microsoft
码云数智-大飞2 小时前
滥用Lombok的@EqualsAndHashCode导致线上事故复盘
开发语言
yong99902 小时前
C# 实时查看硬件使用率(CPU 内存 硬盘 网络)
开发语言·网络·c#
不午休の野猫3 小时前
vs + qt环境编译.sln项目时报无法解析的外部符号metaObject && qt_metacast
开发语言·qt
吴声子夜歌3 小时前
Java——接口的细节
java·开发语言·算法
阿拉金alakin3 小时前
深入理解 Java 锁机制:CAS 原理、synchronized 优化与主流锁策略全总结
java·开发语言
myheartgo-on3 小时前
Java—方 法
java·开发语言·算法·青少年编程
雨落在了我的手上3 小时前
如何学习java?
java·开发语言·学习
神仙别闹4 小时前
基于 C# OpenPGP 的文件管理系统
开发语言·c#