2010-01-17 30 views
3

不確定正確的稱號,但本次討論源於:Initializiation混亂

Do the parentheses after the type name make a difference with new?

在Visual Studio 2008中,當我運行下面的代碼:

struct Stan 
{ 
    float man; 
}; 

int main() 
{ 
    Stan *s1 = new Stan; 
    Stan *s2 = new Stan(); 

} 

檢查當地人,s1有一個隨機值的未初始​​化的浮點數。 s2的值初始化爲0.

但是,如果我添加一個字符串數據成員,兩個實例中的float都是未初始化的。

struct Stan 
    { 
      std::string str; 
     float man; 
    }; 

但是,兩個實例中的字符串都被初始化了。我嘗試添加其他非POD類而不是字符串,但後一種情況只會在添加字符串數據成員時發生。我認爲添加一個字符串仍然保持POD類?如果它不是POD類,那麼它應該有值初始化,不管括號是什麼,對吧?當我添加一個字符串數據成員時,爲什麼浮點數(以及其他原始數據類型)沒有初始化?

+0

'後者'的情況下,原始數據類型沒有初始化,但字符串是。 – 2010-01-17 01:12:49

回答

5

添加字符串從一個POD類停止結構,因爲POD類必須與類型的沒有成員非POD結構和std::string已經(除其他事項外)用戶聲明的構造,這使得它的聚集體類非POD結構。

這是Visual Studio 2008的一個已知錯誤/功能。它不支持非POD類型的C++ 03 值初始化,如第二個示例中的結構。

與第二個示例中的結構一樣,應該發生的情況是float不是由new Stan初始化,而是在new Stan()中初始化爲零。

通過在所有情況下調用該構造函數來初始化具有用戶聲明的默認構造函數的類型,這會發生正確。

請參閱herehere

+0

是的,你的第二句話正是我認爲應該發生的事情。很高興知道這是一個錯誤/功能。 – 2010-01-17 01:28:01

+0

對不起,我編輯過,所以現在是我的第三句話! – 2010-01-17 01:36:19

0

從語言的C++ 98規範的角度來看,您觀察到的行爲是一致的行爲。

第一個示例中的類型是所謂的POD(普通舊數據)類型。當您將()初始值設定項應用於POD類類型時,它將對該類的所有數據成員執行零初始化。

第二個示例中的類型不是POD類型(因爲非POD成員str)。當您將()初始值設定項應用於非POD類類型時,它只會調用類構造函數來執行初始化。在你的情況下,隱式的[編譯器提供的]構造函數將正確初始化str成員,但不會爲man成員做任何事情,這就是爲什麼你會看到垃圾。

同樣,這是C++ 98中的正確行爲。它在C++ 03中進行了更改。在C++ 03中,()初始化器將執行值初始化。根據值初始化的規則,在第二個示例中,man字段也應該初始化爲()初始值程序,並將其初始化爲零。

有關更多詳細說明,另請參閱https://stackoverflow.com/questions/1976185/what-is-the-difference-between-new-myclass-vs-new-myclass

+1

請修復它,MSVC的人! – 2010-01-17 02:03:29