2015-02-09 159 views
12

關於以下內容,是否有任何理由對另一個做一個或者它們大致相同?C++ - 在頭文件中初始化變量與構造函數

class Something 
{ 
    int m_a = 0; 
}; 

VS

class Something 
{ 
    int m_a; 
    Something(int p_a); 
}; 

Something::Something(int p_a):m_a(p_a){ ... }; 
+4

第一個是C++ 11 – Emadpres 2015-02-09 15:25:02

+0

我不指望第一代碼工作的新功能。 (編輯:確定它現在執行) – Aitch 2015-02-09 15:25:11

+1

[C++ 11的可能重複允許非靜態和非const成員的類內初始化。什麼改變?](http://stackoverflow.com/questions/13662441/c11-allows-in-class-initialization-of-non-static-and-non-const-members-what-c​​) – 2015-02-09 15:37:42

回答

5

第一種形式是新的C++ 11所以在這一點上並不十分良好的支持,特別是如果你需要支持各種老版本編譯的。

否則,當C++ 11編譯器可用時,它們應該大致相當。

+0

我以爲我們'我總是能夠像第一種形式一樣初始化'int'。 C++ 11現在是否支持以這種方式初始化多個int?!? – 2015-02-09 15:32:16

+0

@Jonathan Mee你總是可以以前面的方式初始化'靜態'整數,是的。 – 2015-02-09 15:35:10

+1

@JonathanMee:非靜態成員初始化對於C++ 11來說是新的。它還將靜態成員初始化擴展爲任何常量字面類型,而不僅僅是整數。 – 2015-02-09 15:38:52

9

如果您有多個構造函數(並且希望它們都以相同方式初始化成員),或者如果您不需要編寫構造函數,則第一種形式更方便。

如果初始化程序依賴於構造函數參數,或者對於類內初始化過於複雜,則需要第二個參數;如果構造函數複雜,可能會更好,將所有初始化保存在一個地方。 (和它的也需要,如果您有支持前C++ 11級的編譯器。)

0
class Something 
{ 
    int m_a = 0; 
}; 

相當於

class Something 
{ 
    int m_a(0); 
}; 

所以,做

class Something 
{ 
    int m_a;// (0) is moved to the constructor 
public: 
    Something(): m_a(0){} 
}; 

產生一個統一的語法用於需要或不需要運行時輸入的初始化。

個人而言,我不喜歡第一種形式,因爲它看起來像是「聲明然後轉讓」,這是完全的誤解。

+1

除了在這種情況下'int m_a(0);'是不允許的。 – juanchopanza 2015-02-09 16:03:37

+0

詳細說明,只有'= value;'和'{value};'被允許用於類內成員初始值設定項,而不是'(value);'。 – chris 2015-02-09 16:08:29

16

您發佈的兩個代碼片段是不完全相同

class Something 
{ 
    int m_a = 0; 
}; 

這裏指定在編譯時初始化的值,即0

class Something 
{ 
    int m_a; 
    Something(int p_a); 
}; 

Something::Something(int p_a):m_a(p_a){ ... }; 

在這裏,你做這件事運行時(或可能在運行時),與價值p_a不知道,直到調用構造函數。

下面這段代碼更接近你的第一個例子:

class Something 
{ 
    int m_a; 
    Something(); 
}; 

Something::Something() : m_a(0) { /* ... */ }; 

,你必須考慮在這裏是什麼,在第一種情況下,該值在類定義直接出現。這可能會造成不必要的依賴。如果您需要0更改爲1以後會發生什麼情況?在其他形式的初始化將避免它的情況下,直接在類定義中(因此通常在頭文件中)公開該值可能會導致大量代碼的重新編譯,因爲Something::Something() : m_a(0)部分將被整齊地封裝在源中文件並且不出現在頭文件中:

// Something.h - stable header file, never changed 
class Something 
{ 
    int m_a; 
    Something(); 
}; 

// Something.cpp - can change easily 
Something::Something() : m_a(0) { /* ... */ }; 

當然,課堂初始化的好處可能遠遠超過這個缺點。這取決於。你只需要記住它。

+0

對於無意造成昂貴的重新編譯的問題,這些代碼很快就會變得相當昂貴。 – 2016-11-13 12:05:40

1

詳細闡述Christian Hackl的答案。

第一種形式允許初始化m_a並同時具有默認c'tor。或者你甚至可以在你的代碼,並明確定義構造函數與default關鍵字:

class Something 
{  
    int m_a = 0; 

    // explicitly tell the compiler to generate a default c'tor 
    Something() = default; 
}; 

隨着第二種形式,自動生成的默認c'tor會離開m_a未初始化的,所以如果你想初始化一個硬編碼值,你必須寫自己的默認c'tor:

class Something 
{ 
    int m_a; 

    // implement your own default c'tor 
    Something() : m_a(0) {} 
};