簡體   English   中英

標准是否保證初始化順序?

[英]Is the order of initialization guaranteed by the standard?

在下面的代碼片段中,d1的初始化程序是d2,它尚未構造(正確嗎?),D的復制構造函數中的dj是否為未初始化的內存訪問?

struct D
{
    int j;

    D(const D& d) { j = d.j; }
    D(int i) { j = i; }
};

struct A
{
    D d1, d2;
    A() : d2(2), d1(d2) {}
};

C ++標准的哪一部分討論了數據成員的初始化順序?

我現在沒有標准的方便,所以我不能引用該部分,但結構或類成員初始化總是按聲明的順序發生。 構造函數初始化列表中提到成員的順序不相關。

Gcc有一個警告-Wreorder ,當訂單不-Wreorder會發出警告:

-Wreorder (C++ only)
           Warn when the order of member initializers given in the code does
           not match the order in which they must be executed.  For instance:

                   struct A {
                     int i;
                     int j;
                     A(): j (0), i (1) { }
                   };

           The compiler will rearrange the member initializers for i and j to
           match the declaration order of the members, emitting a warning to
           that effect.  This warning is enabled by -Wall.

C ++標准(ISO / IEC 14882:2003 12.6.2 / 5, 初始化基礎和成員 )說:

初始化應按以下順序進行:

- 首先,僅對於如下所述的派生類最多的構造函數,虛擬基類應按它們出現在基類有向無環圖的深度優先從左到右遍歷的順序進行初始化,其中“ “從左到右”是派生類base-specifier-list中基類名稱的出現順序。

- 然后,直接基類應按聲明順序初始化,因為它們出現在base-specifier-list中(無論mem-initializers的順序如何)。

- 然后,非靜態數據成員應按照它們在類定義中聲明的順序進行初始化(同樣不管mem-initializers的順序如何)。

- 最后,執行構造函數的主體。

Bullet point 3保證非靜態數據成員初始化的順序。

在您的示例中,它將失敗:

struct A
{
    D d1, d2;    
    A() : d2(2), d1(d2) {}
};

d1: is initialised first as it is declared first.
d2: is then initialized.

因此,初始化列表將使用對無效對象的引用來構造d1(d2)。

這是使編譯器警告級別盡可能高的一個原因。
另外強制它將所有警告報告為錯誤。

在Meyer的Effective C ++的第13項中解釋/強調了這種現象。 它說析構函數必須按其構造函數的逆序銷毀元素,因此所有構造函數必須以相同的順序初始化元素,因此它們按照它們被聲明的順序(而不是初始化列表的序列)初始化它們。

是。 一個好的編譯器應該警告你A::d2將在A::d1之后初始化。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM