簡體   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