HJ C++11 Day2

Initializer Lists

对于一个类P

class P{
	P(int a, int b){
		cout << "P(int, int), a=" << a << ", b = " << b << endl;
	}
	P(initializer_list<int> initlist){
		cout << "P(initializer_list), values= ";
		for(auto i : initlist)
			cout << i << ' ';
		cout << endl;
	}
}

当运行

//和第一种构造函数完全吻合
P p(77, 5);    //P(int a, int b), a = 77, b = 5
//输入参数为一包,和第二种构造函数更加符合
P q{77, 5};    //P(initializer_list initlist), values = 77 5
//输入参数为一包,只能与第二种构造函数吻合
P r{77, 5, 42};//P(initializer_list initlist), values = 77 5 42
//一包参数,和第二种构造函数更加符合
P s = {77, 5};    //P(initializer_list initlist), values = 77 5 42

讨论:如果只有第一种构造函数时,p不受影响,q也不受影响,因为这一包数据会被拆解为2个数据,恰好符合构造函数的参数要求,但是r会被拆解为3个参数,不符合构造函数的要求,s也不影响。

initializer_list的背后是一个array,但是实际上array是一个迭代器。
编译器在看到大括号{}时就会自动调用initializer_list的私有构造函数,按理说应该没有人能够调用它的私有构造函数,但是编译器具有最高权限,编译器可以调用。实际过程是:编译器在看到大括号{}后,在调用私有构造函数之前,就已经准备好了一个array,然后把这个array的头部传进来,长度也传进来,将其登记起来。

explicit(用于输入参数多于1个实参(多个参数没有默认值)的构造函数)

拒绝隐式的类型转换,让编译器不要自作聪明,在构造函数前声明,则只有被人为明确调用时才会调用,不允许编译器自己偷偷调用。
对于一个类P

class P{
public:
	P(int a, int b){
		cout << "P(int a, int b) \n";
	}
	P(initializer_list<int>){
		cout << "initializer_list \n";
	}
	explicit P(int a, int b, int c){
		cout << "explicit P(int a, int b, int c) \n";
	}
}
void fp(const P&){};

运行下面的代码

P p1(77, 5);   //P(int a, int b)
P p2{77, 5};   //P(initializer_list)
P p3{77, 5, 42};   //P(initializer_list)
P p4 = {77, 5};   //P(initializer_list)
P p5 = (77, 5, 42);  //error
p P6(77, 5, 42);    //explicit P(int a, int b, int c)
P p7 = {77, 5, 42};   //P(initializer_list)

fp({47, 11});       //P(initializer_list)
fp({47, 11, 3});    //error
fp(P{47, 11});       //P(initializer_list)
fp(P{47, 11, 3});    //P(initializer_list)

p P11{77, 5, 42, 500};  //P(initializer_list)
p P12 = {77, 5, 42, 500};  //P(initializer_list)
p P13{10};  //P(initializer_list)

下面重点解释下为什么P p3{77, 5, 42}; 不会报错,但是P p5 = (77, 5, 42); 会报错:
P p3{77, 5, 42}; 属于列表构造,你使用花括号{}初始化时,initializer_list 构造函数会优先被调用,不会再管explicit P(int a, int b, int c)构造函数,所以不会报错。
但是P p5 = {77, 5, 42};属于拷贝构造,拷贝构造会隐式调用P(int a, int b, int c)但是该构造函数前面加了个explicit,导致没有合适的构造函数可以调用,最终导致报错。

你可能感兴趣的:(HJ,C++11新特性,c++,开发语言)