C++11(第一篇)【C/C++复习版】

本文详细介绍了C++11中引入的新特性,包括统一的列表初始化、initializer_list的使用、auto和decltype类型推导、nullptr的引入、范围for的便利性、STL容器更新(array和forward_list)、右值引用和移动语义的重要性,以及完美转发和左值/右值的区分。
摘要由CSDN通过智能技术生成

目录

1、统一的列表初始化

2、所有容器新增initializer_list构造

3、auto、decltype和typeid

4、nullptr 

5、 范围for

6、STL中的变化

array(新容器)

 forward_list(新容器)

 cbegin、cend、crbegin、crend(新方法)

7、右值引用和移动语义(重点)

1)什么是左值?什么是左值引用?

2)什么是右值?什么是右值引用?

 3)什么是移动拷贝/赋值

 4)move

8、完美转发

右值引用和左值引用本身是左值还是右值? 

万能引用


1、统一的列表初始化

一切皆可以用{}初始化,且 = 可以不写 

2、所有容器新增initializer_list构造

注意:这两句代码用的不是同一个语法。

第一句代码是用initializer_list实现的,它是用一个常量数组构造一个initializer_list(原理是它有两个指针,指向数组空间的开始和结束位置),C++11里vector里实现了以initializer_list为参数的构造函数

第二句才是前面提到的列表初始化。

所有容器都实现了以initializer_list为参数的构造函数,都可以用上面的写法。

3、auto、decltype和typeid

1)auto可以进行类型推导,函数指针也可以用auto来定义推导。 

2)但如果我只是想声明一个变量,那么可以用decltype。

decltype(pf1)pf2;这句代码就是推导出pf1的类型然后用这个类型定义一个pf2。

decltype可以用来定义变量,也可以用来做模板实参,就是当一个类型用。

3)typeid也可以推导类型,但它只能打印来看,不能用。

4、nullptr 

nullptr也是C++11的,因为NULL在C语言里被定义成字面量0,会有一些歧义,所以有了nullptr。        

5、 范围for

范围for循环通过遍历给定容器的begin()和end()函数返回的迭代器范围,来遍历容器中的每一个元素。用的比较多,不多讲了。

6、STL中的变化

array(新容器)

相当于静态数组增加了一个越界检查功能。

 forward_list(新容器)

单链表,不支持尾插尾删,insert,erase也只支持了after。比较鸡肋。

 cbegin、cend、crbegin、crend(新方法)

返回const迭代器。

7、右值引用和移动语义(重点)

1)什么是左值?什么是左值引用?

左值是一个数据的表达式(如变量名或解引用的指针),我们可以获取它的地址,一般可以对它赋值,只有左值可以出现在赋值符号的左边,右值不行。左值引用就是对左值的引用,给左值取别名,左值引用的符号是&。

左值引用的使用价值:减少拷贝

1、做参数        2、做返回值     

但左值引用一直没有解决的问题是局部变量无法通过左值引用返回。  

2)什么是右值?什么是右值引用?

右值不能取地址,一般是在赋值符号右边,但不能出现在赋值符号左边。对右值取别名就是右值引用,右值引用的符号是&&。

内置类型的右值叫纯右值,自定义类型的右值叫将亡值

下面两个函数构成重载吗?

答案是构成,虽然两个函数都能用,但编译器会调用更匹配的那个,也是就第二个func,如果没有第二个func,第一个也行。

 3)什么是移动拷贝/赋值

对于右值将亡值,可以通过交换两个对象的资源来减少拷贝。对于下面的例子,加上编译器做出优化,虽然str是左值,但由于它出了作用域就销毁了,编译器会识别str是右值将亡值,然后调用右值引用的拷贝构造,即移动拷贝。

string& operator=(string && s) 和 string& operator=(const string & s)构成重载,如果是右值的拷贝构造,就调用第一个,否则调用第二个

需要深拷贝的类,才需要实现移动赋值。

 4)move

 move可以理解为将一个左值转成右值将亡值,然后将所有权转给另一个对象。

int main() {
    // 创建一个vector对象v1,包含一些整数
    std::vector<int> v1 = {1, 2, 3, 4, 5};

    // 使用std::move将v1的所有权转移给v2
    std::vector<int> v2 = std::move(v1);

    return 0;
}

8、完美转发

右值引用和左值引用本身是左值还是右值? 

int a= 10;
int &r = a;
int &&rr = 10;

r和rr都是左值,否则如果右值引用的属性不是左值的话,下面的场景就无法实现:

s本身是左值,才有可能传给swap(string& s)

万能引用

template<typename T>
void PerfectForward(T && t){
    Fun(t);
}

T&&:这是万能引用,既可以接收左值,也可以接收右值。

如果实参是左值,他就是左值引用(引用折叠)

如果实参是右值,他就是右值引用 

注意:因为左值和右值引用本身一定是左值,所以t本身一定是左值。所以最后无论传的实参是左值还是右值,调用的都是左值引用。

如何让t保持T它原本的属性? 完美转发

template<typename T>
void PerfectForward(T && t){
    Fun(forward<T>(t));
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值