4

我想在课堂上初始化一堆成员以保持源文件更干净。但是,这些对象接受我仅通过构造函数接收的参数,并且可以在构造函数初始化列表中或通过赋值在构造函数中进行初始化。(第二个选项肯定行不通。)这基本上是场景:

在页眉中

class Foo
{

public:
    Foo(Pointer * ptr);

private:

    Pointer * ptr;
    Member m1{ptr, "SomeText"};
    Member m2{ptr, "SomeOtherText"};
}

在 CPP

Foo::Foo(Pointer*ptr) : 
    ptr(ptr) 
{
    // ...
}   

ptr现在的问题是:标准是否说明了and m1/之间的初始化顺序m2?显然,此代码仅在和ptr之前初始化时才有效。m1m2

4

3 回答 3

6

这是由标准保证的,非静态数据成员将按照它们在类定义中的声明顺序进行初始化。它们是如何初始化的(通过默认成员初始化器或成员初始化器列表)以及这些初始化器的顺序无关紧要。

[class.base.init]#13.3

(13.3) - 然后,非静态数据成员按照它们在类定义中声明的顺序进行初始化(同样不管 mem-initializers 的顺序)。

[注意:声明顺序是为了确保基子对象和成员子对象以初始化的相反顺序被销毁。——尾注]

这意味着,初始化顺序将始终是ptr-> m1-> m2

于 2018-09-07T10:49:59.883 回答
1

类定义中的顺序很重要,它决定了初始化的顺序。除了重新定义你的班级(即交换顺序)之外,没有办法逃避这个顺序。

进入构造函数主体后,您可以为任何非常量成员变量的值分配您想要的任何值,但此时它们已经被初始化。如果您想在那之前初始化一个成员,您必须在构造函数主体之前执行它 - 即使用Foo::Foo(Pointer * ptr) : ptr(ptr) {}or 或像使用m1and一样初始化它们m2

于 2018-09-07T10:53:06.657 回答
0

它是标准定义的。成员按照类内的声明顺序进行初始化,因此您的代码完全有效。潜在的危险是构造函数中的初始化顺序与成员顺序不一致 - 然后仍然按照声明顺序初始化字段。

于 2018-09-07T10:42:27.367 回答