一、列表初始化/一致性初始化
- 設計的目的:
- 在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; }