这是来自此主题Initializing fields in constructor - initializer list vs constructor body
的复制粘贴作者解释了以下等同性:
public : Thing(int _foo, int _bar){
member1 = _foo;
member2 = _bar;
}
is equivalent to
public : Thing(int _foo, int _bar) : member1(), member2(){
member1 = _foo;
member2 = _bar;
}
我的理解是
这两个是如何相同的?
答案 0 :(得分:3)
您的理解是正确的(假设member1
和member2
有类型`int)。这两种形式是不等价;在里面
首先,成员根本没有初始化,也不可能
使用直到他们被分配。在第二种情况下,
成员将初始化为0.这两个配方只是
如果成员是具有用户定义的类类型,则等效
构造函数。
答案 1 :(得分:1)
你说得对,但作者也是有点了!
您的解释完全正确,其他人给出的答案也是如此。总之,如果member1
和member2
是非POD类型,则两个代码段是等效的。
对于某些POD类型,它们在某种意义上也是等同的。好吧,让我们再简化一下,假设member1
和member2
的类型为int
。然后,在 as-if-rule 下,编译器允许将第二个代码段替换为第一个代码段。实际上,在第二个片段中,member1
首次初始化为0
的事实是不可观察的。只有_foo
的分配是。这与允许编译器替换这两行的原因相同
int x = 0;
x = 1;
这一个
int x = 1;
例如,我编译了这段代码
struct Thing {
int member1, member2;
__attribute__ ((noinline)) Thing(int _foo, int _bar)
: member1(), member2() // initialization line
{
member1 = _foo;
member2 = _bar;
}
};
Thing dummy(255, 256);
使用选项-O1
使用GCC 4.8.1 。 (__atribute((noinline))__
阻止编译器内联函数)。然后,无论初始化行是否存在,生成的汇编代码都是相同的:
-O1
是否有初始化
0: 8b 44 24 04 mov 0x4(%esp),%eax
4: 89 01 mov %eax,(%ecx)
6: 8b 44 24 08 mov 0x8(%esp),%eax
a: 89 41 04 mov %eax,0x4(%ecx)
d: c2 08 00 ret $0x8
另一方面,使用-O0
编译时,汇编代码会有所不同,具体取决于初始化行是否存在:
-O0
未初始化
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 83 ec 04 sub $0x4,%esp
6: 89 4d fc mov %ecx,-0x4(%ebp)
9: 8b 45 fc mov -0x4(%ebp),%eax
c: 8b 55 08 mov 0x8(%ebp),%edx
f: 89 10 mov %edx,(%eax)
11: 8b 45 fc mov -0x4(%ebp),%eax
14: 8b 55 0c mov 0xc(%ebp),%edx
17: 89 50 04 mov %edx,0x4(%eax)
1a: c9 leave
1b: c2 08 00 ret $0x8
1e: 90 nop
1f: 90 nop
-O0
初始化
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 83 ec 04 sub $0x4,%esp
6: 89 4d fc mov %ecx,-0x4(%ebp)
9: 8b 45 fc mov -0x4(%ebp),%eax ; extra line #1
c: c7 00 00 00 00 00 movl $0x0,(%eax) ; extra line #2
12: 8b 45 fc mov -0x4(%ebp),%eax ; extra line #3
15: c7 40 04 00 00 00 00 movl $0x0,0x4(%eax) ; extra line #4
1c: 8b 45 fc mov -0x4(%ebp),%eax
1f: 8b 55 08 mov 0x8(%ebp),%edx
22: 89 10 mov %edx,(%eax)
24: 8b 45 fc mov -0x4(%ebp),%eax
27: 8b 55 0c mov 0xc(%ebp),%edx
2a: 89 50 04 mov %edx,0x4(%eax)
2d: c9 leave
2e: c2 08 00 ret $0x8
31: 90 nop
32: 90 nop
33: 90 nop
请注意,初始化的-O0
在没有初始化的情况下有四条额外的行(上面标记)而不是-O0
。这些额外的行将两个成员初始化为零。