【问题标题】:Order of initialization of class member variables类成员变量的初始化顺序
【发布时间】:2019-12-20 13:30:12
【问题描述】:

考虑以下代码sn-p:

class A
{
public:
    A(int a, int b) : j(a), i(j + b) {}
    int i, j;
};

int main()
{
    A a(10, 20);
    std::cout << a.i << " " << a.j << std::endl;
    return 0;
}

标准says认为成员变量的初始化顺序是它们被声明的顺序。在这种情况下,i 将在 j 之前初始化。由于j尚未初始化,i = *a garbage value* + 20,然后j10初始化。

代码prints20 10

即,j 在计算 i 时被认为是 0

标准是否保证在这种情况下使用内置类型的默认值?还是只是垃圾值恰好是0?还是未定义的行为

【问题讨论】:

  • "或者只是垃圾值恰好是0?" - 可能在超过 90% 的情况下(当然仍然是 UB)。
  • 还是未定义的行为? 是的。
  • 这应该回答你的问题:stackoverflow.com/a/6032889/5728381

标签: c++ constructor initializer-list


【解决方案1】:

标准是否保证在这种情况下使用内置类型的默认值?

没有。在这种情况下,该值是不确定的。

还是未定义的行为?

是的。读取不确定值的行为是未定义的(窄字符类型 IIRC 除外)。

【讨论】:

    【解决方案2】:

    j + b 是未定义的行为,因为它在允许这样做的特定实例之一之外使用不确定值(j 在其初始化之前的值)(所有这些都与char 变体和@ 987654324@,不是int,不确定值)。

    在 C++20 中,它也会有未定义的行为,因为您在其生命周期之外访问 j。据我所知,在 C++17 和 j 的生命周期开始之前分配其存储空间,因为 j 的初始化是空的。不过,在 C++20 中,空初始化和生命周期的定义发生了变化。

    所以在任何情况下,在初始化之前使用变量都是非常不明智的。

    【讨论】:

      猜你喜欢
      • 2023-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-19
      • 1970-01-01
      相关资源
      最近更新 更多