如果有默认成员初始化,为什么要使用成员初始化列表

Why use member init lists if there is default member initialization

在 C++11 中,引入了 default member initialization。 所以,我只想问为什么必须仍然使用成员初始化列表来支持这些?

例如

如果允许的话

class apple
{
    int i = 10;
};

为什么要使用这个

class apple
{
    int i;
    apple(): i(10) {}
};

有什么具体的优势吗?

成员初始化器列表可以使用特定于构造函数的初始化器来初始化成员。

例如,初始化器可能依赖于构造函数的参数,例如

class apple
{
    int i;
    apple(int i_) : i(i_) {}
};

或在不同的构造函数之间进行更改,例如

class apple
{
    int i;
    apple(foo_type) : i(0) {}
    apple(bar_type) : i(1) {}
};

这两种情况都不能由单个默认成员初始值设定项处理。

这里没有"must",估计要看情况了。

例如,如果初始化值不是常量,或者如果多个构造函数中的每个值都必须不同,则使用初始化列表是有意义的。

如果您必须支持 C++11 之前的版本(这在大型项目中可能比您想象的更常见),您必须始终使用初始化列表。相应地,如果您的大多数代码维护者不熟悉 C++11 功能,可能使用长期存在的机制而不是内联初始化更好。

如果使用 C++11 不是问题,并且您正在跨多个构造函数初始化为单个常量值,那么初始化形式可能更有意义。

如果您不想,则不必使用成员初始值设定项列表。此外,您可以混合使用默认成员初始化和成员初始化列表。这不仅仅是其中之一。默认成员初始值设定项将用于任何未出现在成员初始值设定项列表中的成员。

选择哪一个取决于很多因素。

当成员应始终使用相同的值初始化时,默认成员初始化很有用。这是一个方便的 shorthand,增加了清晰度,因为初始值显示在声明的地方。

另一方面,如果您需要使用运行时确定的不同值来初始化一个成员,则不能使用默认初始化程序来完成;您必须改为在构造函数中执行此操作。

与 C++ 相反,默认成员初始化是一个相对较新的概念,Java 从一开始就有等价物,程序员已经详细讨论了两种不同初始化机制的优点,例如参见 Default constructor vs. inline field initialization