簡體   English   中英

從派生的 class 初始化列表調用基 class 構造函數的順序

[英]Order of calling base class constructor from derived class initialization list

struct B { 
  int b1, b2;  
  B(int, int);
};

struct D : B {
  int d1, d2;
// which is technically better ?
  D (int i, int j, int k, int l) : B(i,j), d1(k), d2(l) {} // 1st Base
// or
  D (int i, int j, int k, int l) : d1(k), d2(l), B(i,j) {} // last Base
};

以上只是一個偽代碼。 實際上,我想知道調用基本構造函數的順序是否重要?

是否有任何情況引起的不良行為(尤其是極端情況)? 我的問題是關於更多技術方面的問題,而不是關於編碼 styles。

您在問題中提到的順序不是“調用基本構造函數的順序”。 實際上,您不能調用構造函數。 用戶不能調用構造函數。 只有編譯器可以調用構造函數。

您可以做的是指定初始值設定項。 在這種情況下(構造函數初始值設定項列表),您正在為一些更大的子對象指定初始值設定項 object。您指定這些初始值設定項的順序無關緊要:編譯器將按照語言規范定義的非常特定的順序調用構造函數,而不管您指定初始值設定項的順序。 始終首先調用基類 class 構造函數(按照基類在 class 定義中列出的順序),然后調用成員子對象的構造函數(同樣,按照這些成員在 class 定義中列出的順序)。

(當涉及到虛擬基類時,這條規則有一些特殊之處,但我決定不在這里包括它們。)

至於不良行為……當然這里也有可能出現“不良行為”。 如果您假設初始化順序取決於您在構造函數初始化列表中使用的順序,當您發現編譯器完全忽略該順序並使用它自己的順序(順序聲明)代替。 比如這段代碼的作者

struct S {
  int b, a;
  S() : a(5), b(a) {}
};

可能期望a首先被初始化,然后ba接收初始值5 ,但實際上這不會發生,因為ba之前被初始化。

訂單定義明確。 它不取決於您在初始化時如何指定它們。
Base class 構造函數B將首先被調用,然后按照聲明的順序調用成員變量( d1d2 )。

解釋@Andrey T 的回答中的評論。

class MyClass1: public MyClass2, public virtual MyClass3
{


};

調用 Base class 構造函數的順序由標准明確定義,將是:

MyClass3  
MyClass2
MyClass1

虛擬 Base class MyClass3優先於 Base Class MyClass2

事物出現在初始化列表中的順序並不重要。 在您的情況下,將始終首先初始化基數 object,然后依次初始化 d1 和 d2。 初始化按派生順序執行,並且成員出現在 class 定義中。

話雖如此,按初始化順序編寫初始化列表通常被認為是一種很好的風格,如果不這樣做,一些編譯器會發出警告。

暫無
暫無

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

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