2009-10-27 248 views
0

我很確定內置類型的數組是單位化的,而UDT數組是默認初始化的。數組初始化

int foo[5]; // will contain junk
Foo foo[5]; // will contain 5 Foo objects that are default initialized

這不管陣列是否被堆棧或堆上分配發生。

但是,我發現很難找到這方面的權威來源。 Bjarne表示:

「數組和結構的成員是默認初始化或不是取決於數組或結構是靜態的」,這並沒有真正地告訴我太多。

我也試過在標準中找到一些東西,但到目前爲止沒有任何結果。

有誰知道權威來源確認上述?

+2

你用'Foo'取決於什麼是例如' Foo' - 如果它是一個POD結構(例如'struct Foo {int x;}'),它將不會被默認初始化。 – 2009-10-27 02:08:08

回答

7

ISO C++ 03大約是權威性,因爲它得到:

甲POD結構是具有式非POD結構的沒有非靜態數據成員的聚合類,非-POD-union(或這種類型的數組)或引用,並且沒有用戶定義的拷貝賦值操作符,也沒有用戶定義的析構函數。同樣,POD-union是一個聚合聯合,它沒有類型非POD-struct,非POD-union(或這種類型的數組)或非引用的非靜態數據成員,也沒有用戶定義的複製賦值運算符並沒有用戶定義的析構函數。 POD類是一個POD結構或POD結合的類。

算術類型(3.9.1),枚舉類型,指針類型和成員類型指針(3.9.2)以及這些類型的cv限定版本(3.9.3)統稱爲標量類型。標量類型,POD結構類型,POD聯合類型(第9章),這些類型的數組和這些類型的cv合格版本(3.9.3)統稱爲POD類型。

要零初始化類型T的對象是指:

  • 如果T是轉換到T的標量類型(3.9),所述對象被設置爲0(零)的值;
  • 如果T是非聯合類類型,則將每個非靜態數據成員和每個基類子對象初始化爲零;
  • 如果T是聯合類型,則該對象的第一個命名數據成員是零初始化的;
  • 如果T是一個數組類型,則每個元素都是零初始化的;
  • 如果T是引用類型,則不執行初始化。

爲默認初始化類型T的對象是指:

  • 如果T是一個非POD類型(第9節),T的默認構造函數被調用(以及初始化病如果T沒有可訪問的默認構造函數,則形成);
  • 如果T是一個數組類型,則每個元素都是默認初始化的;
  • 否則,該對象被零初始化。

要值初始化類型T的對象是指:

  • 如果T是一個類類型(第9節)與用戶聲明的構造(12.1),然後對T中的默認的構造是調用(如果T沒有可訪問的默認構造函數,則初始化不合格);
  • 如果T是一個沒有用戶聲明構造函數的非聯合類類型,那麼T中的每個非靜態數據成員和基類組件都進行了值初始化;
  • 如果T是一個數組類型,則每個元素都進行了值初始化;
  • 否則,對象初始化爲零

靜態存儲的每個對象應在程序啓動時初始化爲零的任何其他初始化發生之前。 [注:在某些情況下,稍後會進行額外的初始化。]

對象的初始值設定項是一組空括號,即(),應進行值初始化。

如果沒有爲某個對象指定初始值設定項,並且該對象是(可能是cv-qualified)非POD類類型(或其數組),則該對象應該被默認初始化;如果該對象屬於const限定類型,則基礎類類型應具有用戶聲明的默認構造函數。否則,如果沒有爲非靜態對象指定初始化方法,則該對象及其子對象(如果有的話)具有不確定的初始值)。如果該對象或其任何子對象屬於const限定類型,則該程序不合格。

對於你的榜樣,int絕對是一個POD類型(這是一個算術類型),因此,本地或外地int型的,在沒有初始化的,將有一個不確定的值。對於Foo,這取決於它是如何定義的 - 粗略地說,如果它沒有構造函數,並且它的所有成員都是POD類型,那麼它本身就是POD類型,並且也不會進行初始化。否則,將調用默認的構造函數。即使如此,這並不意味着成員被初始化 - 規則是遞歸的,所以非POD類型的POD成員將不會被初始化,除非該類型的構造函數明確地(在其初始化器列表中)這樣做。

靜態變量和字段在所有情況下都將被初始化爲零。請注意,這也適用於非POD - 也就是說,類類型的靜態變量保證在其構造函數運行之前遞歸地將所有字段設置爲(T)0

一個得心應手的把戲默認初始化任何集合POD類型是在初始使用{} - 請注意,它的工作原理與結構以及數組:

char s[10] = {}; // all elements default-initialized 
Foo foo = {}; // all fields recursively default-initialized 
1

「數組和結構的成員是默認初始化或不依賴於陣列或結構是否是靜態的」

這是有權威的,雖然也可以更清楚:

  • 陣列並聲明爲static的結構被初始化爲零。
  • 未初始化本地數組和內置類型的結構(,即沒有構造函數的類型)。
+0

「本地數組和結構未初始化。」 - 這是不正確的。 POD類型的本地(和成員!)變量未初始化。非POD類型的本地變量和成員變量是默認初始化的。 – 2009-10-27 01:55:46

+0

@Pavel Minaev:我會說「太籠統」而不是「不正確」 - 儘管如此,更新以反映您的評論。謝謝! – 2009-10-27 02:00:14

1

它說在C++標準,在8.5.9:

如果爲 對象沒有指定初始化,並且該對象是(可能 CV修飾)非POD類的類型(或其中的 ),則該對象應爲 默認初始化;如果對象爲const限定類型的 ,則基礎類類型應具有用戶聲明的默認構造函數 。 否則,如果沒有爲非靜態對象指定初始化程序 ,則 對象及其子對象(如果有) 具有不確定的初始值。