C++11 初始化
C++11 初始化
统一初始化语法
C++11新添加初始化列表 std::initializer_list<>类型,可以通过{}语法来构造初始化列表 。初始化列表是常数;一旦被创建,其成员均不能被改变,成员中的数据也不能够被变动。函数能够使用初始化列表作为参数。
在引入C++ 11之前,有各种不同的初始化语法。在C++ 11中,仍可以使用这些初始化语法,但也可以选择使用新引入的统一的初始化语法。统一的初始化语法用一对大括号{}表示。
std::vector<string> v1 = {"hello", "world", "welcome"};
std::vector<int> v2 = {0, 3, 8, 1, 4};
// 注: vs2012 不支持统一初始化方式{}
类内成员初始化
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> #include <vector> #include <map> class Mem { public: Mem(int i, int j): m(i), n(j) // 初始化列表给m初始化, 可以给const变量赋初值, 以及引用变量赋初值 { // m = i; 错误,不能给const变量赋值 // n = j; 错误,不能给引用变量赋值 } int getM() { std::cout << "m: " << m << std::endl; } const int m; int &n; }; void mytest() { int data = 1; // 使用"="初始化非静态普通成员,也可以 int data{1}; Mem Mem{2, data}; // 对象成员,创建对象时,可以使用{}来调用构造函数 // 注: vs2012 不支持统一初始化方式{} std::string name("xyz"); // 使用()来调用构造函数 return; } int main() { mytest(); system("pause"); return 0; }
列表初始化
C++11引入了一个新的初始化方式,称为初始化列表(List Initialize),具体的初始化方式如下:
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> #include <vector> #include <map> class Person { public: std::string name; int age; }; void mytest() { int a[] = {4,5,6}; int b[]{1,3,5}; // 注: vs2012 不支持 int i = {1}; int j{3}; // 注: vs2012 不支持 // 初始化列表可以用于初始化结构体类型 Person p1 = {"Frank", 25}; std::vector<int> ivec1(3,4); // 其他一些不方便初始化的地方使用,比如std<vector>的初始化,如果不使用这种方式,只能用构造函数来初始化,难以达到效果 std::vector<int> ivec2 = {5,5,5}; // 注: vs2012 不支持 std::vector<int> ivec3 = {1,2,3,4,5}; // 注: vs2012 不支持 return; } int main() { mytest(); system("pause"); return 0; }
防止类型收窄
类型收窄指的是导致数据内容发生变化或者精度丢失的隐式类型转换。使用列表初始化可以防止类型收窄。
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> #include <vector> #include <map> void mytest() { const int x = 1024; const int y = 10; char a = x; // 收窄,但可以通过编译 char *b = new char(1024); // 收窄,但可以通过编译 char c = {x}; // err,收窄,无法通过编译 char d = {y}; // 可以通过编译 unsigned char e{-1}; // err,收窄,无法通过编译 float f{7}; // 可以通过编译 int g{2.0f}; // err,收窄,无法通过编译 float * h = new float{1e48}; // err,收窄,无法通过编译 float i = 1.21; // 可以通过编译 return; } int main() { mytest(); system("pause"); return 0; }