在CPP11之前的不同对象都有各自的初始化方式,于是初始化列表特性的目的在于统一初始化环节
统一初始化
提供了基本类型、数组、自定义类型等不同对象的初始化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| 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); Student s2{ "Mark", 18 };
int a1 {10}; int a2 = {10}; int * arr = new int[4]{ 0, 2, 4, 5 };
|
注意事项:自定义类型是尽量实现对应的构造函数,虽然初始化列表支持使用默认构造按照声明顺序进行初始化,但是从开发规范的角度来说,这种方式容易产生隐藏bug,不易排查
1 2 3 4 5 6 7 8
| struct Student { string m_name; int m_age; };
Student s1{ "Jeson", 18 }; Student s2{ 18, "Jeson" };
|
类型安全
初始化列表可以防止”缩窄”的隐式类型转换,对于小到大的则不做限制
1 2 3 4 5
| int a1 = 3.14; int a2 = {3.14};
double b1 = 3; double b2 = {3};
|
初始化模板类-std::initializer_list
cpp11提供了std::initializer_list模板类,可将其作为构造函数的参数,如果类有接受initializer_list作为参数的构造函数,则初始化列表语法就只能用于该构造函数。
1 2 3 4 5 6 7 8 9 10 11 12 13
| 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 a2(1, 2);
|
参考
- 《C++ Primer Plus(第6版)中文版》