1. 程式人生 > >新特性(2)---一致性初始化,使用者自定義初值列

新特性(2)---一致性初始化,使用者自定義初值列

一致性初始化

引入原因

在沒有引入之前,變數的初始化有許多方式 (如小括號,大括號,賦值號),且不同變數和類又有不同的初始化方式。(如,結構體能用{}初始化,類用{}則會出錯。)

     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;
}