1

如果我有一个结构

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,则更清楚。

我从未见过有人提到过这一点,但似乎只有在确定永远不会更改数据布局的情况下才能安全地使用这样的聚合初始化。那将是罕见的情况,那么是否有“永远不要在非同质结构上使用聚合初始化”的潜规则?

4

1 回答 1

0

重构期间结构的聚合初始化是否安全?

取决于您在这种情况下如何定义“安全”。以及做了什么样的重构。

似乎我的代码可以默默地中断......因为现在SomeStruct s{1,2}意味着x=1, y=2, z=0

这可能完全没问题。为什么不应该将 z 初始化为 0?在您知道它代表什么之前,您无法判断它是否损坏。

这是您可以对课程进行的更良性的更改之一。诸如重新排序成员之类的不同更改肯定需要更改相关代码。

如果您确定永远不会更改数据的布局,您似乎只能安全地使用这样的聚合初始化。

或者,如果预计唯一的更改是可以进行值初始化的新成员。(C 支持指定的初始值设定项,它们甚至可以适应成员顺序的变化。不幸的是,我们在 C++ 中没有它们)。

或者,如果您发现查找和更新聚合初始化没有问题。您应该知道,只要您对聚合进行更改,就会存在这种可能性。

但事实上,构造函数确实提供了一种“实现防火墙”,将用户与成员的更改分离开来。像新成员这样的一些更改可能会提示对构造函数的更改,但缺少构造函数参数确实有助于破坏编译。

那么是否有“永远不要在非同质结构上使用聚合初始化”的潜规则?

当然不是没有你我都考虑过的例外情况。此外,同质性与异质性没有区别。

我会反过来说,在设计公共API 时,应该考虑类的布局是否应该一成不变,或者将成员设为私有并提供构造函数。对于内部 API,如果您能快速完成该类的所有使用,这并不重要。


GCC 有一个警告选项,可以解决您描述的确切情况:(-Wmissing-field-initializers由 启用-Wextra)。如果您提供任何成员初始化程序,但不是全部,它将生成警告。

于 2017-03-08T09:30:00.460 回答