新特性(2)---一致性初始化,使用者自定義初值列
阿新 • • 發佈:2018-11-19
一致性初始化
引入原因
在沒有引入之前,變數的初始化有許多方式 (如小括號,大括號,賦值號),且不同變數和類又有不同的初始化方式。(如,結構體能用{}初始化,類用{}則會出錯。)
int i=1;
int i(1);
int i = int(1);
testStruct struct={"test",10};
testClass class=("test",10);
這樣就很繁瑣,所以引入一致性初始化,也就是說面對的初始化動作,都可以使用相同的語法來操作。也就是使用大括號。
int value[ ] {1,2,3,4};
std::vector< int> v {1,2,3,4,5};
int i {1}
注意1:窄化
然而對於窄化(也就是精度降低或者造成數值變動),對於大括號是不成立的。
也就是說,大括號可以由double轉換成int而無法由int轉換為double。
int i=1.0; //正確
int i2(1.0);//正確
int i3{1.0};//錯誤
int i4={1.0}//錯誤
初值列
眾所周知,全域性變數定義時候預設為0,區域性變數定義時候,是沒有值的即不確定的值,而引入初值列,會使區域性變數得到初始值0/nullptr。
int i;//沒有值
int j{};//初始化為0
int *p;//沒有值
int *p{ };//初始化為nullptr
使用者自定義初值列
提供std::initializer_list<>來進行使用者自定義型別之初值列操作。栗子:
#include<iostream>
#include<cstdio>
using namespace std;
void print(std::initializer_list<int> test)
{
for (auto *p=test.begin();p!=test.end();++p)
{
printf("%d\n",*p);
}
}
int main()
{
print( { 1,2,3,4,5,6 });
system("pause");
return 0;
}
使用者自定義初值列也可以用來類的初始化
#include<iostream>
#include<cstdio>
using namespace std;
class MyClass
{
public:
MyClass() { printf("正常操作"); };
MyClass(std::initializer_list<int> t){ printf("傳參錯誤"); }
~MyClass() {};
private:
};
int main()
{
MyClass test{123};
system("pause");
return 0;
}
當指明實參的建構函式和一個初值列的建構函式一起存在時,使用{}初始化時,初值列的建構函式優先呼叫。
class MyClass
{
public:
MyClass(int x) { printf("正常操作"); };
MyClass(std::initializer_list<int> t){ printf("傳參錯誤"); }
~MyClass() {};
private:
};
int main()
{
MyClass test(123);//呼叫第一個建構函式
MyClass test1{123};//呼叫初值列建構函式
MyClass test2(123,789);//呼叫初值列建構函式
MyClass test3={123};//呼叫初值列建構函式
system("pause");
return 0;
}