C++ 資料成員初始化 @ C++11/17(inline variable)

| | 0 Comments| 14:53
Categories:

在 Heresy 來看,C++ 類別(或結構)的資料成員(data member)的初始化,其實一直很麻煩…因為要初始化他的值,不能像一般變數一樣,在宣告的同時就同時定義,變成要初始化的話,會變成一定要去定義類別的建構子才行…

以前的寫法,基本上就是:

class CTest
{
public:
	int m_iValue1;
public:
	CTest() : m_iValue1(128)  {}
};

這樣寫法一個比較麻煩的地方,就是如果有好幾個建構子的話,那每個建構子都給各自去給初始化的值。

例如:

class CTest
{
public:
	int m_iValue1;
public:
	CTest() : m_iValue1(128){}
	CTest(bool) : m_iValue1(128) {}
};

這樣的缺點,就是初始化的值會寫好幾次,在變數多、如果要修改會很麻煩,很有可能會不小心出現不一致的狀況…

而在以往的標準下,比較好的方法,可能會是把這些資料成員的的初始化都包成一個函式,讓建構子去呼叫了。

不過,在 C++11 的時候,C++ 標準終於支援 non-static data member initializer 了!

所以如果只是要初始化資料成員,就可以簡單寫成:

class CTest
{
public:
	int m_iValue1 = 128;
};

這樣一來,就算有不同的建構子,值的初始化的部分也都只有一個地方,要修改會變得很方便,而且也更好閱讀了~

而如果是靜態資料成員(static data member)呢,在以前的標準下,其實是一個更麻煩的東西…

在類別內部宣告時,並沒有真的去定義他,定義的部分,則是需要另外寫在外面…像下面就是一個例子:

class CTest
{
public:
	static int m_iValue1;
};
int CTest::m_iValue1 = 128;

而如果 CTest 這個類別是寫在 header 檔的話,那這個靜態資料成員的定義,變成一定得開一個 cpp 檔來編譯,才不會因為多次 include 造成多重定義。

到了 C++17,由於加入了「inline variable」的特性,允許針對變數加上「inline」來確保他只會有一份,所以可以直接寫成:

class CTest
{
public:
	inline static int m_iValue1 = 128;
};

如此一來,要使用類別的靜態資料成員就比以前方便多了。


另外,同樣是因為「inline variable」,現在全域變數(global variable)也可以透過加上 inline,來在宣告的時候同時定義、初始化了~

inline int iGlobal = 10;

這樣,就不必像以前一樣,還得用 extern 的方法來玩了。

這樣對於要寫 header-only 的函式庫的人還說,真的方便很多啊!


參考:

Leave a Reply

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *