C++11 FAQ中文版:類成員的內部初始化
類內部成員的初始化
在C++98標準裡,只有static const宣告的整型成員能在類內部初始化,並且初始化值必須是常量表達式。這些限制確保了初始化操作可以在編譯時期進行。例如:
int var = 7; class X { static const int m1 = 7; // 正確 const int m2 = 7; // 錯誤:無static static int m3 = 7; // 錯誤:無const static const int m4 = var; // 錯誤:初始化值不是常量表達式 static const string m5 = “odd”; //錯誤:非整型 // … };
C++11的基本思想是,允許非靜態(non-static)資料成員在其宣告處(在其所屬類內部)進行初始化。這樣,在執行過程中,需要初始值時建構函式可以使用這個初始值。考慮下面的程式碼:
class A {
public:
int a = 7;
};
這等同於:
class A {
public:
int a;
A() : a(7) {}
};
從程式碼來看,這樣可以省去一些文字的輸入,但是真正受益的是擁有多個建構函式的類。在大多數情況下,所有的建構函式都會使用成員變數的常見初始值:
class A { public: A(): a(7), b(5), hash_algorithm(“MD5″), s(“Constructor run”) {} A(int a_val) : a(a_val), b(5), hash_algorithm(“MD5″), s(“Constructor run”) {} A(D d) : a(7), b(g(d)), hash_algorithm(“MD5″), s(“Constructor run”) {} int a, b; private: // 雜湊加密函式可應用於類A的所有例項 HashingFunction hash_algorithm; std::string s; // 指示的字串變數將持續整個物件的生命週期 };
hash_algorithm和s每個都有一個單獨的預設值的事實會由於雜亂的程式碼而不明顯,這會在程式維護時造成麻煩。作為替代,可以將資料成員的初始值提取出來:
class A { public: A(): a(7), b(5) {} A(int a_val) : a(a_val), b(5) {} A(D d) : a(7), b(g(d)) {} int a, b; private: //雜湊加密函式可應用於類A的所有例項 HashingFunction hash_algorithm{“MD5″}; //指示的字串變數將持續整個物件的生命週期 std::string s{“Constructor run”}; };
如果一個成員同時在類內部初始化時和建構函式內被初始化,則只有建構函式的初始化有效(這個初始化值“優先於”預設值)(譯註:可以認為,類內部初始化先於建構函式初始化進行,如果是對同一個變數進行初始化,建構函式初始化會覆蓋類內部初始化)。因此,我們可以進一步簡化:
class A {
public:
A() {}
A(int a_val) : a(a_val) {}
A(D d) : b(g(d)) {}
int a = 7;
int b = 5;
private:
//雜湊加密函式可應用於類A的所有例項
HashingFunction hash_algorithm{“MD5″};
//指示的字串變數將持續整個物件的生命週期
std::string s{“Constructor run”};
};
或參見:
- the C++ draft section “one or two words all over the place”; see proposal.
自己試試:
X.h
class X
{
private:
int a = 5;
int b = 6;
};
main.cpp
#include "X.h"
int main()
{
X x;
return 0;
}
g++ -std=c++0x main.cpp
X.h:15:10: 對不起,尚未實現: non-static data member initializers
X.h:15:10: 錯誤: ISO C++ 不允許在類內初始化非常量靜態成員‘a’
X.h:16:10: 對不起,尚未實現: non-static data member initializers
X.h:16:10: 錯誤: ISO C++ 不允許在類內初始化非常量靜態成員‘b’
g++ --version
g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
Copyright © 2011 Free Software Foundation, Inc.