明確初始化
C++ 支援兩種形式的明確初始化。
在括號中提供初始設定式清單:
String sFileName( "FILE.DAT" );
括號清單中的項目是類別建構函式的引數。 這種初始化格式可以使用一個以上的值進行物件初始化,也可以與 new 運算子搭配使用。 例如:
Rect *pRect = new Rect( 10, 15, 24, 97 );
使用等號初始化語法提供單一初始設定式。 例如:
String sFileName = "FILE.DAT";
雖然上述範例和第一個清單項目的 String 範例有相同的作用,但無法配合可用存放區上所配置的物件調整其語法。
等號右方的單一運算式是類別的複製建構函式的引數;因此,必須是能夠轉換為類別類型的類型。
請注意,由於初始化中的等號 (=) 與指派運算子不同,因此多載 operator= 對初始化沒有影響。
等號初始化語法不同於函式樣式的語法,即使在許多情況下兩者會產生相同的程式碼。 不同之處在於,使用等號語法時,編譯器必須假設下列事件正在依序發生:
建立與初始化物件類型相同的暫存物件。
將暫存物件複製到物件。
編譯器必須能夠存取建構函式,之後才能執行這些步驟。 即使編譯器在大部分情況下可以排除暫時建立和複製步驟,若複製建構函式無法存取,就會導致等號初始化失敗 (在 /Za, /Ze 下 (停用語言擴充功能))。 參考下列範例:
// spec1_explicit_initialization.cpp
// compile with: /Za
class anInt {
anInt( const anInt © ) {} // private copy constructor
public:
anInt( int ) {} // public constructor
};
int main() {
// Access-control violation.
// Attempt to reference private copy constructor.
anInt myInt = 7; // C2248
anInt myInt2(7); // Correct; no copy constructor called.
}
當呼叫函式時,會使用下列格式概念初始化值所傳遞的類別類型引數及值所傳回的物件:
type-name name = value
例如:
String s = "C++";
因此,隨後跟著的引數類型必須是可以轉換為以引數傳遞之類別類型的類型。 類別的複製建構函式以及接受實質引數類型的使用者定義轉換運算子或建構函式,都必須是公用的。
在使用 new 運算子的運算式中,可用存放區上所配置的物件會利用下列格式進行概念初始化:
type-name name**(** initializer1, initializer2, ... initializern )
例如:
String *ps = new String( "C++" );
基底類別元件的初始設定式和類別的成員物件也會利用此方式進行概念初始化。(如需詳細資訊,請參閱初始化基底和成員)。