一、列表初始化/一致性初始化
- 设计的目的:
- 在C++11之前,如何初始化一个变量或对象的概念比较混淆。初始化的场景可以发生在:小括号、大括号或赋值操作符中
- C++11引入了“列表初始化/一致性初始化”,意思为:面对任何初始化动作,你可以使用相同语法,就是使用大括号
- 例如下面的都是正确的:
int units_sold = 0;
int units_sold = { 0 };
int units_sold{ 0 };
int units_sold(0);
int values[]{ 1,2,3 };
std::vector<int> v{ 2,3,5,7,11,13,17 };
std::vector<std::string> cites{
"Berlin","New York","London"
}
局部基础数据类型的默认初始化
- 对于局部变量的定义,如果我们没有给出初始值,那么这个变量定义的值是不明确的未知的
- 如果我们使用{}对普通数据类型的变量进行定义,即使没有给出初始值,那么会根据数据类型进行默认初始化
- 例如:
int i; //乱值 int j{}; //0 int *p; //p指向未知地址 int *q{}; //q为nullptr
禁止窄化
- “窄化”意为:精度降低或造成数值变动
- 对于一般的赋值与初始化,允许窄化的发生
- 对于大括号的初始化,其不允许窄化的发生,如果有,那么编译将不通过。主要的原因是为了防止数据在转换中的丢失
- 例如:
int x1(5.3); //正确,允许double向int转变,但是x1为5 int x2 = 5.3; //正确,同上 int x3{ 5.3 }; //错误,不允许,因为造成了数据丢失 char c1{ 7 }; //正确,7也属于char char c2{ 99999 }; //错误,99999不属于char的范围,不允许转换 std::vector<int> v1{ 1,2,3,4,5 }; //正确 std::vector<int> v2{ 1.2,8,1.5 }; //错误,其中含有double数据
二、std::initializer_list
- 为了支持“用户自定义类型之初值列”概念,C++11提供了class template std::initializer_list<>,用来支持以一些列值进行初始化
- initializer_list在另一篇文章中已经介绍过,可以参阅:https://blog.csdn.net/qq_41453285/article/details/91895105
- 本文就不详细介绍语法了,介绍一些演示案例,语法参阅上面的链接
一些演示案例
- std::initializer_list提供begin()和end()两个成员。例如:
void print(std::initializer_list<int> vals) { for (auto p = vals.begin(); p != vals.end(); ++p) std::cout << *p << std::endl; } print({ 12,3,5,4,8 });
- 在类的构造函数使用std::initializer_list。例如:
class P { public: P(int, int); P(std::initializer_list<int>); }; int main() { P p(77, 5); //调用给P(int, int) P p2(77, 5, 20); //错误, P p3{ 77,5 }; //调用P(std::initializer_list<int>) P p4 = { 77,5 }; //调用P(std::initializer_list<int>) P p5{ 77,5,10,15 }; //调用P(std::initializer_list<int>) return 0; } //备注,如果P没有提供P(std::initializer_list<int>),那么上面的p3、p4将 //调用P(int, int),p5初始化将错误
- explicit将抑制类的构造函数转换行为。例如:
class P { public: P(int, int); explicit P(int, int, int); }; int main() { P p(77, 5); //正确,调用P(int, int) P p2(77, 5, 20); //正确,调用explicit P(int, int, int) P p4 = { 77,5 }; //正确,调用P(int, int) //错误,explicit关键字抑制initializer_list列表使用P(int, int, int)构造函数 P p4 = { 77,5,10 }; return 0; }