C++2.0新特性(二)——<一致性初始化、Initializer_list 、for循环、explicit>

一、一致性初始化(uniform initialization)

  之前初始化时存在多个版本,让使用者使用时比较混乱,现在提供一种万用的初始化方法,就是使用大括号。

  原理解析:当编译器看到大括号包起来的东西时,会生成一个initializer_list<T>(initializer_list它其实是关联一个array<T,n>),然后再调用构造函数时,一个个从array分解取出来然后调用构造函数,但是如果这个函数自身提供了initializer_list<T>参数类型的构造函数时,则不会分解而是直接传过去。

 

// 初值列:强迫初始化为 0 (或nullptr).
int i; // i 初始化为未定义值.
int j{}; // j 初始化为 0 (大括号可以用来设初值)
int * p; // p 初始化为未定义值.
int * q{}; // q 初始化为 0 (大括号可以用来设初值)

// 窄化(精度降低或造成数值变动)对大括号而言是不成立的.
int x0(3.4); // ok.
int x1 = 3.4; // ok.
int x2 { 3.4 }; // wrong.(不允许窄化数据处理,其实我的编译器只给警告)
int x3 = { 3.4 }; // wrong.(不允许窄化数据处理,其实我的编译器只给警告)
std::vector<int> v1 { 1, 2, 3 }; // ok.
std::vector<int> v2 { 1.1, 2.2, 3.3 }; // wrong.(不允许窄化数据处理,其实我的编译器只给警告)

二、Initializer_list

注意:只要编译器遇到大括号里面有一些数,再传值的时候都会去生成一个initializer_list<T>去处理,这个和前面一章节提到的不定参数模板相比,这个必须类型要一致,而后者则可以类型随意组合

三、for循环

注意:1、上图中申明引用类型的速度快很多,因为引用相当于指针的操作只操作4个字节,而非引用的速度开销随着数据类型所占空间增长而增大,且声明引用后的修改将直接影响到集合中数据的值。

      2、用for操作容器时,标准库规定,关联容器都不允许通过迭代器修改修改容器的值,也就是说上面申明为引用的for循环无法修改关联容器里的数值

四、explicit

  explicit关键字一直存在,只能作用在构造函数中, 目的是阻止编译器进行不应该允许的构造函数进行隐式转换(也就是说不让编译器自作聪明),声明为explicit的构造函数不能进行隐式转换,只能允许使用者明确调用构造函数;

  在C++2.0中,explicit可以支持不止一个参数的构造函数使用(之前只能支持传入一个实参)

1、2.0以前,explicit只能作用在一个实参的构造函数上

 1 #include <iostream>
 2 class Single{
 3 
 4 public:
 5     //普通构造函数(单一实参)
 6     Single(int a,int b = 0):num(a)
 7     {}
 8 private:
 9     int num;
10 };
11 
12 class SingleMore {
13 public:
14     //explicit 显示申明构造函数(单一实参)
15     explicit SingleMore(int a) :num(a)
16     {}
17 private:
18     int num;
19 };
20 
21 
22 #if 1
23 int main(int argc, char* argv[])
24 {
25     Single single(3);
26     Single single2 = 4;
27 
28     SingleMore singleMore(3);
29     SingleMore singleMore2 = 4;//编译报错,E0415 不存在从 "int" 转换到 "SingleMore" 的适当构造函数
30 
31     return 0;
32 }
33 #endif

2、2.0以后explicit可以适用多个实参的构造函数

 

猜你喜欢

转载自www.cnblogs.com/laiyingpeng/p/11310266.html