C++程序中哪些情況下變量會自動初始化

至今對於C++的初始化機制還存在一些疑慮,大致整理如下

初始化的語法

我們首先來解決語法的問題。 C語言中在聲明時用=即可完成初始化操作。但我們偏向於使用C++風格(本文中均指面向對象程序設計風格)來初始化內置類型:

// C 風格
int i = 3;
int arr[] = {1, 2, 3};

// C++ 風格
int i(3);
int i = int(3);
int *p = new int(3);
int[] arr = new int[]{1, 2, 3};
在C語言中int a;表示聲明瞭整型a但未初始化,而C++中的對象總是會被初始化的,無論是否寫了圓括號或者是否寫了參數列表,例如:
int basic_var;      // 未初始化:應用"默認初始化"機制
CPerson person;     // 初始化:以空的參數列表調用構造函數

默認初始化規則

定義基本數據類型變量(單個值、數組)的同時可以指定初始值,如果未指定會默認初始化(default-initialization),什麼是"默認初始化"呢?

  • 棧中的變量(函數體中的自動變量)和堆中的變量(動態內存)會保有不確定的值;
  • 全局變量和靜態變量(包括局部靜態變量)會初始化爲零。

C++11: If no initializer is specified for an object, the object is default-initialized; if no initialization is performed, an object with automatic or dynamic storage duration has indeterminate value. Note: Objects with static or thread storage duration are zero-initialized, see 3.6.2.

所以函數體中的變量定義是這樣的規則:

int i;                    // 不確定值
int i = int();            // 0
int i = new int;          // 不確定值
int i = new int();        // 0

靜態和全局變量的初始化

未初始化的和初始化爲零的靜態/全局變量編譯器是同樣對待的,把它們存儲在進程的BSS段(這是全零的一段內存空間)中。所以它們會被"默認初始化"爲零。

關於進程的內存空間分配見進程的地址空間:TEXT,DATA,BSS,HEAP,STACK一文。

成員變量的初始化

成員變量分爲成員對象和內置類型成員,其中成員對象總是會被初始化的。而我們要做的就是在構造函數中初始化其中的內置類型成員。 還是先來看看內置類型的成員的"默認初始化"行爲。

內置類型的成員變量的"默認初始化"行爲取決於所在對象的存儲類型,而存儲類型對應的默認初始化規則是不變的。 所以爲了避免不確定的初值,通常會在構造函數中初始化所有內置類型的成員。Effective C++: Item 4一文討論瞭如何正確地在構造函數中初始化數據成員。

封閉類嵌套成員的初始化

再來探討一下當對象聚合發生時成員變量的"默認初始化"行爲,同樣還是隻關注於基本數據類型的成員。

規則還是是一樣的,默認初始化行爲取決於它所屬對象的存儲類型。 封閉類中成員對象的內置類型成員變量的"默認初始化"行爲取決於當前封閉類對象的存儲類型,而存儲類型對應的默認初始化規則仍然是不變的

原文地址
關於進程的內存空間分配見進程的地址空間:TEXT,DATA,BSS,HEAP,STACK一文。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章