新特性(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;
}

猜你喜欢

转载自blog.csdn.net/qq_35651984/article/details/83246209