C++11新特性知识点整理

c++11有哪些新特性?

关键字及语法:
auto 关键字:编译器可以根据初始值自动推导出类型。我们不必费心去推导复杂表达式的类型。
但是需要注意几点:
使用auto关键字的变量必须进行初始化。
auto关键字不能用于函数传参以及数组类型的推导。(数组类型会推导为指针)
可能存在二义性,例如,auto s=“abc”,s是一个const char*而不是string 类型。
代码跨平台性降低,因为别的编译器不一定支持。

nullptr关键字:nullptr是一种特殊类型的字面值,它可以被转换成任意其他类型的指针类型;而NULL一般宏定义为0,在遇到重载时可能会出现问题。

STL容器:
unordered_map,unordered_set

智能指针
c++11新增了shared_ptr和weak_ptr等类型的智能指针,用于解决内存管理的问题。

初始化列表:使用初始化列表可以对类进行初始化

右值引用:基于右值引用可以实现移动操作,消除两个对象交互时不必要的对象拷贝,节省运算存储资源,提高效率。

noexcept: 指定某个函数不会抛出异常,紧跟在函数的参数列表后面

Lambda表达式:

什么是Lambda表达式

Lambda表达式定义一个匿名函数,并且可以捕获一定范围内的变量,其定义如下:
[capture list](params list)->return type{function body}

[capture list] 是一个lambda所在函数中定义的局部变量的列表,可以捕获所在函数的局部变量可以直接用,还可以直接用局部static变量以及全局变量.
可以进行值捕获
引用捕获
隐式捕获

(params list) 参数列表,与普通函数的参数列表一致,如果不需要,可以省略

mutable 修饰符,默认情况下lambda函数总是一个const函数,mutable可以取消其常量性.在使用该修饰符时,参数列表不可省略

{statement}函数体,内容与普通函数一样,除了可以使用参数之外,还可以使用所捕获的变量.

作用:常用于STL库中,在某些场景下可用于简化仿函数的使用,提高复杂代码的开发速度,轻松在函数内重用代码,无需费心设计接口.

什么是右值引用,跟左值又有什么区别?

为了支持移动操作和完美转发,新标准引入了一种新的引用类型-右值引用。所谓右值引用就是必须绑定到右值的引用,通过&&而不是&来获得右值引用。它有一个重要的性质,只能绑定到一个将要销毁的对象,所以可以自由地将一个右值引用的资源移动到另一个对象中。

什么是移动操作?

  • 在重新分配内存的过程中,我们都是将旧内存的元素拷贝到新内存,但这是不必要,可以移动元素去新的内存空间,就可以大幅度提升性能。
  • 还有一个原因是IO类或unique类不包含能被共享的对象(如指针或IO缓冲),这些类的对象不能拷贝但可以移动。

实现移动操作需要为其定义移动构造函数和移动赋值运算符。

移动构造函数的第一个参数是该类型的一个右值引用。因为右值引用总是绑定到一个将要销毁的值,并且确保销毁它是无害的,这样就可以完成移动,资源的所有权已经归属新创建的对象。

  • 过程:它接管内存之后,将给定对象中的指针置为nullptr。这样就给定了从给定对象的移动操作,此对象将继续存在,源对象将被销毁。

使用移动构造函数的要求?

移动构造函数一般要求移动操作过程不抛出异常。
还有就是移后源对象必须可析构。
类默认使用拷贝构造函数,如果一个类定义了拷贝构造函数和拷贝赋值运算符,编译器不会为其默认生成移动构造函数和移动赋值运算符。
比如说,如果vector使用移动操构造函数,那么在移动过程中,如果只移动了一部分而不是全部,发生异常,但是原空间的元素不存在了,这时候就无法继续。

什么是完美转发?

某些函数需要将其一个或多个实参连同类型不变地转发给其他函数。
我们可以使函数参数是指向模板类型参数的右值引用,它对应的实参的const属性和左值或右值保持。

左值和右值的区别:

1.简单记忆就是:左值可以位于赋值语句的左侧,右值则不能。
2.当一个对象被用作右值的时候用的是对象的值;用作左值的时候,用的是对象的身份。(也就是在内存中的位置)
3.左值具有持久状态,右值暂存,要么是字面常量,要么是表达式求值过程中创建的匿名对象。
4.需要用到右值的地方可以用左值代替,实际用的是它的值,但是不能把右值当做左值。
5.左值能对表达式取地址,右值不能对表达式取地址

左值引用和右值引用的区别:

1.变量是左值,因此我们不能将一个右值引用绑定到一个变量上,而左值引用可以。
2.右值引用只能绑定到临时对象,该对象具备两个性质,所引用的对象将要销毁且该对象没有其他用户。
左值引用则不能绑定到要求转换的表达式,字面常量,或是返回右值的表达式。
3.还有一个重要的特征是:右值引用不能绑定到一个右值引用类型的变量上。
例:int &&rr1=42 将右值引用绑定到一个字面值,此rr1现在是一个右值引用变量,所以不能再多一个右值引用绑定到这个rr1

std:move函数什么作用?

int &&rr3=std::move(rr1) rr1在上面
当我们调用move函数是告诉编译器:我们现在有一个左值,我们希望像一个右值一样处理它。之后我们对这个对象除了复制或销毁它,我们将不再使用它
如果没有移动构造函数,只有拷贝构造函数。那么此时使用move处理一个右值引用怎么处理?答案是将这个右值引用当成一个const左值引用进行拷贝处理。

关于c++ 三/五法则

  1. 需要析构函数的类也需要拷贝构造函数和拷贝赋值函数。
  2. 需要拷贝操作的类也需要赋值操作,反之亦然。
  3. 析构函数不能是删除的
  4. 如果一个类有删除的或不可访问的析构函数,那么其默认和拷贝构造函数会被定义为删除的。
  5. 如果一个类有const或引用成员,则不能使用合成的拷贝赋值操作。键字的作用
发布了40 篇原创文章 · 获赞 23 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/suoyudong/article/details/104888785