2010-11-17 109 views
44

我在C++以下類定義:如何在C++類的初始化程序列表中初始化member-struct?

struct Foo { 
    int x; 
    char array[24]; 
    short* y; 
}; 

class Bar { 
    Bar(); 

    int x; 
    Foo foo; 
}; 

,並想在酒吧類的初始化初始化「foo」的結構(及其所有成員)爲零。可以這樣做:

Bar::Bar() 
    : foo(), 
    x(8) { 
} 

...?

或者foo(x)在初始化程序列表中做了什麼?

或者是結構甚至從編譯器自動初始化爲零?

+3

請注意,成員應該按照與聲明相同的順序在初始化列表中列出,而您首先聲明'x',但在初始化列表中第二個聲明它。 – 2010-11-17 09:52:55

回答

49

首先,您應該(必須!)閱讀關於POD和聚合的c++ faq。在你的情況,Foo確實是一個POD類和foo()值初始化

要值初始化 類型的物體T是指:

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

所以,是的,foo將被初始化爲零。需要注意的是,如果你從Bar構造去掉這個初始化,foo只會默認初始化

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

+2

如果foo被定義爲const成員? – RezaPlusPlus 2011-09-09 21:41:26

8

在標準C++中,您需要爲Foo創建一個ctor。

struct Foo { 

    Foo(int const a, std::initializer_list<char> const b, short* c) 
    : x(a), y(c) { 
    assert(b.size() >= 24, "err"); 
    std::copy(b.begin(), b.begin() + 24, array); 
    } 

    ~Foo() { delete y; } 

    int x; 
    char array[24]; 
    short* y; 
}; 

class Bar { 

    Bar() : x(5), foo(5, {'a', 'b', ..., 'y', 'z'}, 
    new short(5)) { } 

    private: 

    int x; 
    Foo foo; 
}; 

C++ 0x中你可以使用統一的初始化列表,但你仍然需要Foo的析構函數:

class Bar { 

    Bar() : x(5), foo{5, new char[24]{'a', 'b', ..., 'y', 'z'}, 
    new short(5)} { } 
    ~Bar() { delete[] foo.array; delete foo.y;} 
    } 
    private: 

    int x; 
    Foo foo; 
}; 

爲默認初始化foo(如Bar() : foo(), x(8) { }),你需要給富默認構造函數。

+2

這是有點不清楚你在哪裏使用C++ 03 vs C++ 0x。 IIRC'initializer_list'是C++ 0x的一部分。除了你的第二個codeblock,你還創建了兩個內存泄漏。 – 2010-11-17 10:14:25

+0

@Fabio:謝謝你指出,編輯 – erjot 2010-11-17 13:31:59

+0

現在你有一個雙重刪除('foo.y')和一個內存泄漏(來自'new char [24]',另外,我不確定(但我可能會這裏是錯誤的),這是使用'initializer_list'的方式) – 2010-11-17 19:03:17