2009-06-11 220 views
2

我目前正在學習一門C++課程並試圖深入理解整個事情。 我想出了一些理論,這將是巨大的,如果有人能證實他們:變量初始化和構造函數

每個變量(本地,全局staic,會員和非會員)都保證有第一次使用

之前調用它的構造函數

像int這樣的基本類的ctors基本上是no-ops,所以我們明確地賦值了一個值,沒有默認的零值。

以下類在語義上是相同的(並且應該產生相同代碼)

class A 
{ 
    int n; 
}; 

class A 
{ 
    int n; 
public: 
    A() : n() {} 
}; 

class A 
{ 
    int n; 
public: 
    A() { n = int(); } 
}; 

變量n爲在所有情況下仍然未初始化。

編輯:

這似乎是我absolutetly低估了這個問題的複雜性,我大部分的假設是錯誤的。現在Iam仍然試圖找出對象初始化的基本規則。

回答

3

您可能會發現this有趣。

新Foo和新 美孚()之間的區別是,前者將 未初始化,而後者將是當富 是POD類型 缺省初始化(爲零)。所以,不使用帶有括號,成員「一」 可以包含垃圾,但與 括號「a」將永遠被初始化 爲0

+1

我覺得這個說法很難相信。 class Bar {int n; }是一個POD,因爲它是隱式定義的,因此它是/平凡/(來自ISO的正式術語)。然而,它是存在的,並且'新酒吧'和'新酒吧()`稱它。在任何情況下Bar :: Bar()都不會初始化Bar :: n – MSalters 2009-06-11 10:04:31

+0

「class B {int n;};」 *不是* POD,因爲它包含一個私有的非靜態成員'n'。但是,如果它被定義爲「class B {public:int n;};」那麼它將是一個POD,所以當您執行「新Bar()」時,'n'將被初始化。 – 2009-06-11 10:59:04

+1

新手是否有可能完全理解這個主題?似乎有這麼多的規則和例外:-( – codymanix 2009-06-11 11:22:23

4

恐怕你錯了。當你說:

int n = int(); 

然後n(和所有其他POD類型)將零初始化。

此外,還要確保你是在你對初始化和分配之間的差別心裏很清楚 - 這是在C語言很重要++:

int n = int(); // initialisation 
n = 0;   // assignment 
1

否 表單時,該變量只在第一種情況下沒有初始化。

對於具有用戶定義構造函數的類的成員,情況很簡單:總是調用構造函數。

內置類型(和「普通舊數據」結構)可能會保持未初始化狀態,如第一個示例中所示。儘管它們沒有用戶提供的構造函數,但使用構造語法(您的其他兩個示例)將它們初始化爲零。

這個稍微棘手的規則的原因是爲了避免不必要的開銷;例如,如果你定義:

struct S 
{ 
    int array[1024*1024]; 
}; 

僅爲分配值,你需要他們,你不想讓編譯器零粉飾4MB內存,只要你構建一個意圖。

1
class A 
{ 
    int n; 
}; 

只分配內存,沒有爲n進行初始化。


class A 
{ 
    int n; 
public: 
    A() : n() {} 
}; 

這裏n與0


class A 
{ 
    int n; 
public: 
    A() { n = int(); } 
}; 

這裏n首先構造(沒有任何默認值),然後 int()導致一個臨時INT被初始化創建值爲0 然後將其分配給n;