C++ struct中的默认值和构造函数顺序

C++ struct中的默认值和构造函数顺序,c++,constructor,default-value,C++,Constructor,Default Value,我知道我们可以为结构成员设置默认值。例如,我可以为这些成员设置默认值: struct Foo { int a = 0; int b = 1; int c; } 假设成员c有另一个构造函数: struct Foo { int a = 0; int b = 1; int c; foo(int input_c): c(input_c) {} } 在这种情况下,当我构造一个Foo时,构造的顺序是什么?如果我这样做 Foo(100) 我的理解是a和b都是默认先构造的,然后

我知道我们可以为结构成员设置默认值。例如,我可以为这些成员设置默认值:

struct Foo {
  int a = 0;
  int b = 1;
  int c;
}
假设成员c有另一个构造函数:

struct Foo {
  int a = 0;
  int b = 1;
  int c;
  foo(int input_c): c(input_c) {}
}
在这种情况下,当我构造一个Foo时,构造的顺序是什么?如果我这样做

Foo(100)
我的理解是a和b都是默认先构造的,然后c被赋值为100,对吗

-------------更新---------------------

我困惑的一部分也是执行的顺序。对于默认值,是否已在构造函数之前执行

例如,我可以改变我的Foo

struct Foo {
  int a = 0;
  int b = 1;
  int c = -1;
  foo(int d) {
    c += d;     // Does c always started with -1?
  }
}

是的,成员将按照它们在类中声明的顺序进行初始化


因此,当您调用
Foo(100)
时,
a
b
将被初始化为默认值,然后
c
将被初始化为
100

初始化的顺序非常严格,它始终是成员声明的顺序

首先,除非被初始化列表推翻,否则将应用所有默认的类内初始值设定项(按照声明成员的顺序)

然后使用构造函数初始化列表,并按照声明的顺序初始化其中列出的所有成员。如果列出的任何成员也有类内初始值设定项,则这些初始化项不会发生,初始化列表将获胜并用于初始化成员

然后执行构造函数体。此时,所有成员都已通过类内初始化或初始值设定项列表进行初始化。但是构造函数主体可以选择将新值分配给那些初始化的成员

在任何情况下,对于给定的成员
foo
,它将由类内初始化(如果有的话)或初始化列表(如果有的话)初始化,或者默认初始化。无论用于初始化它的方法是什么,该初始化总是在它之前声明另一个成员之后和之后声明另一个成员之前发生

例如:

struct s {
    int a = 1;
    int b = 42;
    int c = 666;
    int d;
    int e;
    s() : e(3), b(123) {
        c = 7;
    }
};
上面的代码总是先初始化
a
,因为它有一个类内初始值设定项,所以将使用它。它的值将是
1

b
第二次初始化。它有一个类内初始值设定项,但构造函数初始化列表推翻了这一点。它将被初始化为值
123

然后将
c
初始化为值
666

d
未初始化/或者更确切地说;默认初始化,对于
int
与未初始化相同,但对于其他类型,如
std::string
意味着初始化为空字符串-这取决于类型是否具有可用值

然后将
e
初始化为值
3
。这发生在最后,因为它是最后声明的。它在构造函数的初始化列表中列出的顺序是无关的

然后执行构造函数主体,并为
c
分配值
7
。因此,它被初始化并随后分配给-这通常是低效的


对象构造现在已经完成。

我以前已经回答过这个问题;一秒钟,我只做了几次()。初始化的顺序始终是在类/结构中声明成员的顺序。@JesperJuhl是的,但这里有两件事:成员的顺序和构造函数的顺序。我可以有多个构造函数,然后有构造函数顺序,对吗?@WhatABeautifulWorld不重要。此外,在成员初始化列表中列出内容的顺序并不重要。如果成员是按照a、b、c的顺序声明的,那么这就是它们初始化的顺序。你的第一段与下两段相矛盾(你只是构建了一个不重要的例子)。如果
d
有一个相等或大括号的初始值设定项,而
b
没有呢。根据你的第一句话,顺序仍然是abcde,但根据你答案的下一部分,顺序是acdbe。@Ben我不太明白我的答案有多不清楚(请随意编辑)。初始化顺序始终为abcde,但任何给定元素是否由类内值或初始化列表初始化取决于是否有一个条目是初始化列表。如果有,则始终获胜,如果没有,则使用类内初始化。如果我没有说清楚,请随意编辑和改进我的措辞。或者如果我完全搞砸了什么,请告诉我。我不知道如何在不完全破坏你的句子结构的情况下说清楚。问题是您将初始值设定项视为一个组,将其成员视为一个组,并将构造函数初始值设定项列表中提到的成员视为另一个组。事实上,没有组,每个成员(实际上,每个子对象,基类实例在成员之前处理)在移动到下一个成员并对其应用相同的规则集之前都被单独和完整地处理。@Ben Yes。我同意。每个成员(或基本对象,首先)都按照声明的顺序分别初始化。它们初始化为的值是从构造函数初始化列表中获取的值,如果不存在,则是类内初始化器。但这一切都是按申报顺序发生的。如果我发布的答案不清楚,我很抱歉。我希望这些评论能够纠正这一点。我相信我知道这是怎么回事,但我可能缺乏恰当表达的语言技能。如果你觉得答案+评论仍然不清楚或有误导性,请投否决票。