1、在給結(jié)構(gòu)體賦值的時候撼嗓,可以使用一對大括號來進行賦值,賦值過程中會按照結(jié)構(gòu)體成員順序來進行賦值欢唾;
struct initTest
{
int nNum;
string str;
};
initTest o = { 1, "初始化" }; //第一種初始化方式
initTest o2{ 1, "初始化" }; //第二種初始化方式
初始化的類型是否按照順序指定的呢且警?
傳入一個錯誤的類型試試,看下編譯器會提示什么礁遣。
從編譯器的錯誤提示中可以看到斑芜,第一個參數(shù)類型已經(jīng)被確定為int類型。
2祟霍、初始化列表初始化類
class initClass
{
public:
initClass(int nC, string str) {};
};
initClass o = { 2, "初始化" }; //第一種初始化方式
initClass o2{ 1, "初始化" }; //第二種初始化方式
3杏头、初始化同類型不定個數(shù)參數(shù)
C++11把初始化列表的概念綁到一個叫做std::initializer_list的模板上,這允許構(gòu)造函數(shù)或其他函數(shù)將初始化列表做為參數(shù).例如:
template<class T>
class initClass
{
public:
initClass(initializer_list<T> initList) {};
};
initializer_list<int> oList{ 1, 2, 3, 4, 5, 6, 7 };
initClass<int> o{ oList };
initializer_list<double> oListd{ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0 };
initClass<double> oD{ oListd };
這個構(gòu)造函數(shù)是一種特殊的構(gòu)造函數(shù),叫做初始化列表構(gòu)造函數(shù)(initializer-list-constructor)
函數(shù)統(tǒng)一類型入?yún)⒁部梢允褂茫?/p>
void FunctionName(initializer_list<float> list);
FunctionName({1.0f, -3.45f, -0.4f});
4寞埠、標準容器的統(tǒng)一初始化
C++11之前初始化一個vector,需要調(diào)用多次push_back函數(shù)進行初始化排嫌。
vector<double> oDList;
oDList.push_back(1.0);
oDList.push_back(2.0);
C++11可以這么實現(xiàn):
vector<double> oDList{ 1.0, 2.0 };
vector<double> oDList = { 1.0, 2.0 };
vector<double> oDList({ 1.0, 2.0 });
5淳地、非靜態(tài)類成員賦值
C++11之前只有靜態(tài)成員在聲明的時候可以賦初值。C++11讓非靜態(tài)成員也可以在聲明的時候賦值帅容。
class initClass
{
public:
initClass() {};
private:
int m_nC = 0;
string m_str = "";
};
如果初始化列表對類initClass的兩個賦過初值的成員變量進行了另外的初始化颇象,那么賦值的內(nèi)容會被覆蓋。
小測試一下:
修改代碼如下:
class initClass
{
public:
initClass(const int nC, const string str) : m_nC(nC), m_str(str) {};
int getNc() { return m_nC; };
string getStr() { return m_str; };
private:
int m_nC = 0;
string m_str = "";
};
initClass test1{ 10, "test" };
cout << "initClass::m_nC:\t" << test1.getNc() << endl;
cout << "initClass::m_str:\t" << test1.getStr() << endl;
測試結(jié)果:
6并徘、對象構(gòu)造的改進
C++11以前類的構(gòu)造函數(shù)不允許調(diào)用該類的其它構(gòu)造函數(shù);每個構(gòu)造函數(shù)都必須自己或者調(diào)用一個公共的成員函數(shù)來構(gòu)造類的全部成員.例如:
class SomeType1
{
public:
SomeType1(int new_number) : number(new_number) {}
SomeType1() : number(42) {}
private:
int number;
};
class SomeType2
{
public:
SomeType2(int new_number) { init(new_number); } //必須調(diào)用一個公共初始化函數(shù)進行初始化成員
SomeType2() { init(42); }
private:
void init(int new_number) { number = new_number; }
private:
int number;
};
而且,基類的構(gòu)造函數(shù)不能直接暴露給派生類;每個派生類必須實現(xiàn)自己的構(gòu)造函數(shù)哪怕基類的構(gòu)造函數(shù)已經(jīng)夠用了.非靜態(tài)數(shù)據(jù)成員不能在聲明的地方初始化.它們只能在構(gòu)造函數(shù)中初始化.
C++11為這些問題提供了解決方案.C++11允許構(gòu)造函數(shù)調(diào)用另一個構(gòu)造函數(shù)(叫做委托構(gòu)造).這允許構(gòu)造函數(shù)利用其它構(gòu)造函數(shù)的行為而只需增加少量的代碼.C#,java和D語言都提供了這種功能. C++的語法如下:
class SomeType1
{
public:
SomeType1(int new_number) : number(new_number) {}
SomeType1() : SomeType1(42) {}
private:
int number;
};
注意:這個例子可以通過給new_number設定一個默認參數(shù)來達到相同的效果.但是,這種新語法可以讓這個默認值在實現(xiàn)中來設置而不是在接口中設置.這帶來的一個好處就是,對庫代碼的維護者而言,在接口中(頭文件中)聲明默認值,這個默認值被嵌入到了調(diào)用端;要改變這個默認值的話,調(diào)用端的代碼都需要重新編譯.但委托構(gòu)造可以在實現(xiàn)中(CPP文件中)來改變這個默認值, 這樣調(diào)用端的代碼就不需要重新編譯,只用重新編譯這個庫就可以了.