考虑以下代码,其中我们D
根据 的另一部分来初始化 的一部分D
:
struct c {
c() : D{rand(), D[0]} {}
int D[2];
};
int main() {
c C;
assert(C.D[0] == C.D[1]);
}
上述程序是否定义明确?我们可以安全地使用同一个数组的一部分来初始化它的另一部分吗?
考虑以下代码,其中我们D
根据 的另一部分来初始化 的一部分D
:
struct c {
c() : D{rand(), D[0]} {}
int D[2];
};
int main() {
c C;
assert(C.D[0] == C.D[1]);
}
上述程序是否定义明确?我们可以安全地使用同一个数组的一部分来初始化它的另一部分吗?
数组成员可以自引用初始化吗?
是的。
struct c {
int a[3];
c() : a{4, a[0], 3} {} // a[0] is initialized to 4.
// a[1] is initialized to whatever a[0] is. (4)
// a[2] is initialized to 3.
};
但是考虑这个例子:
struct c {
int a[3];
c() : a{a[1], 4, a[1]} {} // a[0] is initialized to whatever a[1] is.(Garbage value)
// a[1] is initialized to 4.
// a[2] is initialized to what a[1] is now (4).
};
这里 in 的第一个元素a
将是 in 的任何值a[1]
,这很可能是垃圾值。第二个元素被初始化为4
,第三个元素被初始化为现在a[1]
的值,即值4
。
此外,当您未在 中列出数组中的所有元素时,{}
未列出的元素将被默认初始化:
struct c {
int a[5]; // notice the size
c() : a{a[1], 2, 3, 4}{} // a[0] will get value that is in a[1]
// but since a[1] has garbage value,
// it will be default initialized to 0.
// a[1] = 2
// a[2] = 3
// a[3] = 4
// a[4] is not listed and will get 0.
};
但是,列出已初始化的元素将为您提供所需的值。
使用上面的例子:
struct c {
int a[5];
c() : a{1, a[0], 3, 4}{} // a[0] = 1
// a[1] = 1
// a[2] = 3
// a[3] = 4
// a[4] is not listed and will get 0.
};
聚合初始化的效果是:
每个数组元素或非静态类成员,按照类定义中数组下标/外观的顺序,从初始化列表的相应子句复制初始化。
你的代码看起来不错。然而不知何故令人困惑。
编写 不是一个好习惯
D{rand(),D[0]}
,因为当构造函数运行时,不必先执行 rand() 然后执行 D[0],这完全取决于编译器,可以先执行 D[0],在这种情况 d[1] 将包含垃圾值。它完全取决于编译器,它可以先编译第二个参数,然后再编译第一个参数,反之亦然,执行此语句可能会导致未知行为。