【1】“就地”聲明
C++98中,支持在類聲明的時候使用等號"="初始化類中靜態成員變量,這種聲明方式我們稱之為“就地”聲明。
但是,C++98要求靜態成員必須滿足常量性,而且類型必須是整型或者枚舉型,而非靜態成員變量的初始化則必須在構造函數中進行。
如下示例:
1 class Init 2 { 3 public: 4 Init() : a(0) 5 {} 6 Init(int d) : a(d) 7 {} 8 private: 9 int a; 10 const static int b = 0; 11 int c = 1; //成員,無法通過編譯 12 static int d = 0; //成員,無法通過編譯 13 static const double e = 1.3; //非整型或者枚舉型,無法通過編譯 14 static const char* const f = "e"; //非整型或者枚舉型,無法通過編譯 15 };
如上各種情況均無法通過編譯。
【2】C++11中的區別
在C++11中,允許使用 等號= 或者 花括號{} 進行就地的非靜態成員變量初始化。如下示例:
1 struct C 2 { 3 C(int i, int j) :c(i), d(j) 4 {}; 5 6 int c; 7 int d; 8 }; 9 10 struct init 11 { 12 int a = 1; 13 string b{ "hello" }; 14 C c{ 1, 3 }; 15 };
從第12、13、14行可以看到,使用等號或花括號進行就地初始化。
如此使用后的注意事項:
[1] 初始化列表的效果總是優先於就地初始化。如下示例:
1 #include <iostream> 2 using namespace std; 3 4 struct Test 5 { 6 Test() {}; 7 Test(int i) : c(i) 8 {}; 9 10 int c = 2; 11 }; 12 13 int main() 14 { 15 Test c1; 16 Test c2(500); 17 18 cout << c1.c << endl; // 2 19 cout << c2.c << endl; // 500 20 }
[2] 對於非常量的靜態成員變量,C++11與C++98保持一致:
仍然還是要在頭文件以外的位置定義它,這會保證編譯時,類靜態成員的定義最后只存在於一個目標文件中。
如下示例:
1 // 正確情況: 2 struct S 3 { 4 S() {}; 5 S(int i) : s(i) {}; 6 7 int s = 2; 8 static int p; 9 }; 10 11 int S::p = 3; 12 13 // 錯誤情況: 14 struct C 15 { 16 C() {}; 17 C(int i) : c(i) {}; 18 19 int c = 2; 20 static int d = 3; //報錯 Non-const static data member must be initialized out of line 21 };
[3] 相對於傳統的初始化列表,在類聲明中對非靜態成員變量進行就地列表初始化可以降低程序員的工作量。
當然,我們只在有多個構造函數,且有多個多個成員變量的時候可以看到新方式帶來的便利。如下示例:
1 #include <string> 2 using namespace std; 3 4 class Mem 5 { 6 public: 7 Mem(int i) : m(i) 8 {} 9 10 private: 11 int m; 12 }; 13 14 class Group 15 { 16 public: 17 Group() {} // 這里就不需要初始化data、mem、name成員了 18 Group(int a) : data(a) {} // 這里就不需要初始化mem、name成員了 19 Group(Mem m) : mem(m) {} // 這里就不需要初始化data、name成員了 20 Group(int a, Mem m, string n) : data(a), mem(m), name(n) 21 {} 22 23 private: 24 int data = 1; 25 Mem mem{0}; 26 string name{" Group"}; 27 };
good good study, day day up.
順序 選擇 循環 總結