如果我有结构
SomeStruct
{
double y;
double x;
};
我在某处初始化它像
SomeStruct s{1,2}; //y=1 x=2
然后,如果我将结构重新排序为
,我的代码似乎可以默默地中断SomeStruct
{
double x;
double y;
double z;
};
因为现在SomeStruct s{1,2}
意味着x = 1,y = 2,z = 0
编辑: 提出的一个论点是构造函数具有相同的问题,这是正确的,但在那里你通常可以看到参数名称和命令 - 如果使用任何现代IDE,则更清楚如此。
我还没有看到有人提过这个,但是如果您确定永远不会对数据布局进行更改,那么您似乎只能安全地使用聚合初始化。那将是罕见的情况,那么是否有一条潜规则“从不在非齐次结构上使用聚合初始化”?
答案 0 :(得分:0)
重构期间struct的聚合初始化是否安全?
取决于您如何定义" safe"在这种背景下。进行了什么样的重构。
似乎我的代码可以默默地破解......因为现在
SomeStruct s{1,2}
意味着x=1, y=2, z=0
哪个可能完全没问题。为什么不应该将z初始化为0?在你知道它代表什么之前,你无法判断它是否已被破坏。
这是您可以对课程进行的更为温和的改变之一。一个不同的变化,例如重新排序成员,更确定地需要更改相关代码。
如果您确定永远不会对数据布局进行更改,那么您似乎只能安全地使用此类聚合初始化。
或者,如果预期唯一的更改是新的成员,可以进行值初始化。 (C支持指定的初始化程序,这些程序甚至可以适应成员顺序的变化。不幸的是,我们在C ++中没有它们。)
或者,如果您没有发现查找和更新聚合初始化的问题。每当您对聚合进行更改时,您应该知道存在这种可能性。
但实际上,构造函数确实提供了一种实现防火墙"将用户与成员的更改分离开来。像新成员这样的一些更改可能会提示对构造函数进行更改,但缺少构造函数参数会有助于破坏编译。
所以有一个未说明的规则"永远不会在非同构结构上使用聚合初始化"?
当然不是没有你和我考虑过的例外。同样,同质异质性没有区别。
我会以另一种方式翻转视角,并说在设计 public API时,您应该考虑是否应该将类的布局设置为一成不变,或者将成员设置为私有提供构造函数。对于内部API,如果您能够快速完成课程的所有使用,那么这并不重要。
GCC有一个警告选项,可以解决您描述的确切情况:-Wmissing-field-initializers
(由-Wextra
启用)。如果您提供任何成员初始值设定项,它将生成警告,但不是全部。