C++11特性(笔记一)
目录
一.C++11的{}初始化
二.C++11中的std::initializer list(主要用于初始化)
三.右值引用和移动语义
3.1 左值和右值
3.2 左值引用和右值引用
3.3 移动构造 和 移动赋值(窃取资源,不需要分配新的内存)
四.引用折叠(别名:万能引用)
五. 可变参数模板
一.C++11的{}初始化
1. C++11以后想统一初始化方式,试图实现一切对象皆可用{}初始化,{}初始化也叫做列表初始化。
2. 内置类型支持,自定义类型也支持,自定义类型本质是类型转换,中间会产生临时对象,最后优化了以后变成直接构造。
3. {}初始化的过程中,可以省略掉=
两个例子:
平时初始化map
现在初始化的map
二.C++11中的std::initializer list(主要用于初始化)
1. C++11库中提出了-个 std::initializer_list 的类,这个类的本质是底层开一个数组,将数据拷贝过来,std::initializer list 内部有两个指针 分别指向数组的 开始和结束。
主要用于初始化:
三.右值引用和移动语义
无论左值引用 还是 右值引用,都是给对象 取别名。
3.1 左值和右值
左值是一个表示数据的表达式(如变量名或解引用的指针),一般是有持久状态,存储在内存中,我
们可以获取它的地址,左值可以出现赋值符号的左边,也可以出现在赋值符号右边。定义时 const
修饰符后的左值,不能给他赋值,但是可以取它的地址。
右值(临时对象)也是一个表示数据的表达式,要么是字面值常量、要么是表达式求值过程中创建的临时对象等,右值可以出现在赋值符号的右边,但是不能出现出现在赋值符号的左边,右值不能取地址。
3.2 左值引用和右值引用
1. int & r1 = x; int&& rr1 = y; 第一个语句就是左值引用,左值引用就是给左值取别名,第二个就是右值引用,同样的道理,右值引用就是给右值取别名。
2. 左值引用不能直接引用右值,但是const左值引用可以引用右值
3. 右值引用不能直接引用左值,但是右值引用可以引用move函数move(左值), move函数的本质差不多是强转左值为右值。
注意: 需要注意的是变量表达式都是左值属性,也就意味着一个右值被右值引用绑定后,右值引用变量表达式的属性是左值!
插入小知识:延长生命周期:右值引用可用于为临时对象延长生命周期,const的左值引用也能延长临时对象生存期,但这些对象无法被修改。
3.3 移动构造 和 移动赋值(窃取资源,不需要分配新的内存)
1. 移动构造函数是一种构造函数,类似拷贝构造函数,移动构造函数要求第一个参数是该类类型的右值引用,如果还有其他参数,额外的参数必须有缺省值。
2. 移动赋值是一个赋值运算符的重载,他跟拷贝赋值构成函数重载,类似拷贝赋值函数,移动赋值函数要求第一个参数是该类类型的右值引用。
移动构造(只需要swap窃取):
移动赋值(只需要swap窃取):
3. 对于像string/vector这样的深拷贝的类或者包含深拷贝的成员变量的类,移动构造和移动赋值才有意义,因为移动构造 和 移动赋值的第一个参数都是右值引用的类型,他的本质是要“窃取”引用的右值对象的资源!!!而不是像拷贝构造和拷贝赋值那样去拷贝资源,从提高效率。
四.引用折叠(别名:万能引用)
1. 右值引用折叠成右值引用,所有其他组合均 折叠成左值引用。
左值引用不可以折叠:
引用折叠例子:
五. 可变参数模板
4.1 基本语法及原理
C++11支持可变参数模板,也就是说支持可变数量参数的 函数模板和 类模板,可变数目的参数被称为参数包,存在两种参数包:模板参数包,表示零或多个模板参数; 函数参数包: 表示零或多个函
数参数。
template<class ...Args> void Func(Args... args){}
template <class ...Args> void Func(Args&... args)
template <class ...Args> void Func(Args&&... args){} //万能模板