繁体   English   中英

没有初始化程序列表与带有空括号对的初始化程序列表

[英]No initializer list vs. initializer list with empty pairs of parentheses

这是该主题的复制粘贴。 初始化构造函数中的字段-构造函数列表与构造函数主体

作者解释了以下等效性:

    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;
    }

我的理解是

  • 片段1是默认初始化的情况(由于缺少初始化列表)
  • 片段2是值初始化(空对括号)的情况。

这两个当量如何?

您的理解是正确的(假设member1member2类型为int)。 这两种形式是等价的。 在第一个实例中,成员根本没有初始化,并且只有在分配成员后才能使用。 在第二种情况下,成员将初始化为0。仅当成员是具有用户定义的构造函数的类类型时,这两个公式才等效。

你是正确的,但笔者是一种权利呢!

您的解释完全正确,其他人给出的答案也一样。 总之,如果member1member2是非POD类型,则这两个代码段是等效的。

对于某些POD类型,它们在某种意义上也是等效的。 好吧,让我们简化一些,并假设member1member2类型为int 然后,在常规规则下允许编译器将第一个代码段替换为第二个代码段。 确实,在第二个片段中,无法观察到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);

在GCC 4.8.1中使用选项-O1 __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多了四行(上面标记)。 这些额外的行将两个成员初始化为零。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM