在CPP11之前的不同對象都有各自的初始化方式秫舌,于是初始化列表特性的目的在于統(tǒng)一初始化環(huán)節(jié)
統(tǒng)一初始化
提供了基本類型、數(shù)組谣辞、自定義類型等不同對象的初始化
class Student
{
public:
Student(string name, int age)
: m_name(name), m_age(age) {
cout << __FUNCTION__ << endl;
}
private:
string m_name;
int m_age;
};
Student s1("Jeson", 18); // 傳統(tǒng)方式
Student s2{ "Mark", 18 }; // 初始化列表
int a1 {10};
int a2 = {10};
int * arr = new int[4]{ 0, 2, 4, 5 };
<font color=red>注意事項(xiàng):自定義類型是盡量實(shí)現(xiàn)對應(yīng)的構(gòu)造函數(shù)甸私,雖然初始化列表支持使用默認(rèn)構(gòu)造按照聲明順序進(jìn)行初始化欧芽,但是從開發(fā)規(guī)范的角度來說,這種方式容易產(chǎn)生隱藏bug朴摊,不易排查</font>
struct Student
{
string m_name;
int m_age;
};
Student s1{ "Jeson", 18 }; // 編譯通過; s1.m_name == Jeson ; s1.m_age == 18
Student s2{ 18, "Jeson" }; // 編譯不通過
類型安全
初始化列表可以防止"縮窄"的隱式類型轉(zhuǎn)換默垄,對于小到大的則不做限制
int a1 = 3.14; // 編譯通過
int a2 = {3.14}; // 編譯不過,vs2017報(bào)錯(cuò)(error C2397: 從“double”轉(zhuǎn)換到“int”需要收縮轉(zhuǎn)換)
double b1 = 3; // 編譯通過
double b2 = {3}; // 編譯通過
初始化模板類-std::initializer_list
cpp11提供了std::initializer_list
模板類甚纲,可將其作為構(gòu)造函數(shù)的參數(shù)口锭,如果類有接受initializer_list作為參數(shù)的構(gòu)造函數(shù),則初始化列表語法就只能用于該構(gòu)造函數(shù)。
class A
{
public:
A(std::initializer_list<int> list) {
cout << "A(std::initializer_list<int> list)" << endl;
}
A(int a, int b) {
cout << "A(int a, int b)" << endl;
}
};
A a1{ 1, 2 }; // A(std::initializer_list<int> list)
A a2(1, 2); // A(int a, int b)
參考
- 《C++ Primer Plus(第6版)中文版》