class A { public: int x[100]; };
声明A a
不会初始化对象(字段x
中的垃圾值会看到)。
以下内容将触发初始化:A a{}
或auto a = A()
或auto a = A{}
。
三者中的任何一个是否应该优先考虑?
接下来,让我们将其作为另一个类的成员:
class B { public: A a; };
B
的默认构造函数似乎负责a
的初始化。
但是,如果使用自定义构造函数,我必须处理它。
以下两个选项有效:
class B { public: A a; B() : a() { } };
或:
class B { public: A a{}; B() { } };
两者中是否有任何一个首选?
答案 0 :(得分:3)
class A { public: int x[100]; };
声明
A a
不会初始化对象(垃圾会看到) 字段中的值x)。
正确A a
是在没有初始化程序的情况下定义的,不符合default initialization的任何要求。
1)以下内容将触发初始化:
A a{};
是;
a{}
执行list initialization {}
为空,则A
为汇总,则<{3}}为aggregate initialization。A() = delete;
(如果&#39; A&#39;仍然被视为聚合)2)以下内容将触发初始化:
auto a = A();
是;
()
构建prvalue临时值
()
为空,则A
。
A(A&&) = delete;
A(const A&) = delete; A(A&&) = default;
3)以下内容将触发初始化:
auto a = A{}
是;
{}
构建prvalue临时值
{}
为空,则A
是聚合,则可以是聚合初始化。 A
。
A(A&&) = delete;
A(const A&) = delete; A(A&&) = default;
A() = delete;
(如果&#39; A&#39;仍然被视为聚合)三者中的任何一个是否应该优先考虑?
显然,您应该更喜欢A a{}
。
接下来,让我们将其作为另一个类的成员:
class B { public: A a; };
B
的默认构造函数似乎负责初始化a
。
不,这不正确。
A
的默认构造函数,但不会初始化成员。不会触发直接或列表初始化。此示例的语句B b;
将调用默认构造函数,但会留下A
数组的不确定值。1)但是,如果使用自定义构造函数,我必须处理它。该 以下两个选项有效:
class B { public: A a; B() : a() { } };
这将有效;
: a()
是constructor initializer,a()
是成员初始值设定项,是member initializer list的一部分。 ()
,如果()
为空,则使用value initialization。 2)或:
class B { public: A a{}; B() { } };
这将有效;
a
现在有non-static data member initializer,如果您使用聚合初始化且编译器为not fully C++14 compliant,则可能需要构造函数对其进行初始化。{}
{}
为空,A
是聚合,则aggregate initialization可能会变为some exceptions。 a
是唯一成员,则不必定义默认构造函数,并且将隐式定义默认构造函数。显然你应该选择第二种选择。
就我个人而言,我更喜欢在任何地方使用大括号,auto
用于std::initializer_list
以及构造函数可能将其误认为class B { public: A a{}; };
的情况:
std::vector
对于std::vector<int> v1(5,10)
和std::vector<int> v1{5,10}
,(5,10)
构造函数的行为会有所不同。使用{5,10}
,您可以获得5个元素,每个元素的值为10,但使用std::initializer_list
,您会得到两个元素,分别包含5和10,因为如果您使用大括号,则a()
是首选。这在Scott Meyers的Effective Modern C ++第7项中得到了很好的解释。
特别针对member initializer lists,可以考虑两种格式:
()
如果a{}
为空,则变为value initialization。{}
如果A a()
为空,也会变为value initialization。在成员初始化列表中,幸运的是,没有最烦恼的解析风险。在初始化列表之外,作为一个语句,A a{}
将声明一个函数与{{1}},这本来是清楚的。此外,list initialization还可以防止缩小转化次数。
因此,总而言之,这个问题的答案取决于您想要确定的内容,这将决定您选择的形式。对于空初始化器,规则更宽容。