新的类功能
默认成员函数
原C++类中有有个默认成员函数:
构造函数
析构函数
拷贝构造函数
拷贝赋值重载
- 取地址重载
- const 取地址重载
最重要的是前4个,后两个用处不大。默认成员函数就是我们不写编译器会生成一个默认的。
C++11 新增了两个:移动构造函数和移动赋值运算符重载
。
针对移动构造函数和移动赋值运算符重载有一些需要注意的点如下:
如果没有自己实现移动构造函数,且没有实现析构函数 、拷贝构造、拷贝赋值重载中的任意一个。
那么编译器会自动生成一个默认移动构造。默认生成的移动构造函数,对于内置类型成员会执行逐成员按字节拷贝,自定义类型成员,则需要看这个成员是否实现移动构造,如果实现了就调用移动构造,没有实现就调用拷贝构造。如果没有自己实现移动赋值重载函数,且没有实现析构函数 、拷贝构造、拷贝赋值重载中的任意一个
,那么编译器会自动生成一个默认移动赋值。默认生成的移动构造函数,对于内置类型成员会执行逐成员按字节拷贝,自定义类型成员,则需要看这个成员是否实现移动赋值,如果实现了就调用移动赋值,没有实现就调用拷贝赋值。(默认移动赋值跟上面移动构造完全类似)如果提供了移动构造或者移动赋值,编译器不会自动提供拷贝构造和拷贝赋值。
示例:
如果实现了拷贝构造、拷贝赋值和析构
,没有实现移动构造和移动赋值那么会自动生成移动赋值或者移动构造吗?
场景一:
如果没有实现了拷贝构造、拷贝赋值和析构
,并且没有实现移动构造和移动赋值那么会自动生成移动赋值或者移动构造吗?
场景二:
类成员变量的初始化
C++11允许在类定义时给成员变量初始缺省值,默认生成构造函数会使用这些缺省值初始化,这个我们在类和对象默认就讲了,这里就不再细讲了。
default
C++11可以让你更好的控制要使用的默认函数。假设你要使用某个默认的函数,但是因为一些原因这个函数没有默认生成。比如:我们提供了拷贝构造,就不会生成移动构造了,那么我们可以使用default关键字显示指定移动构造生成。
示例:
delete
如果能想要限制某些默认函数的生成,在C++98中,是该函数设置成private,并且只声明补丁已,这样只要其他人想要调用就会报错。在C++11中更简单,只需在该函数声明加上=delete即可,该语法指示编译器不生成对应函数的默认版本,称=delete修饰的函数为删除函数。
可变参数模板
C++11的新特性可变参数模板能够让您创建可以接受可变参数的函数模板和类模板,相比C++98/03,类模版和函数模版中只能含固定数量的模版参数,可变模版参数无疑是一个巨大的改进。然而由于可变模版参数比较抽象,使用起来需要一定的技巧,所以这块还是比较晦涩的。现阶段呢,我们掌握一些基础的可变参数模板特性就够我们用了,所以这里我们点到为止,以后大家如果有需要,再可以深入学习。
递归函数方式展开参数包
逗号表达式展开参数包
使用场景
一般使用在emplace这个插入接口中。
那么emplace和普通的push_back有什么区别吗?
可以看到emplace的效率比较高一点点。
lambda表达式
在讲lambda表达式之前先看一个场景。
当我们对自定义类型排序时,我们要自己实现和传仿函数。
随着C++语法的发展,人们开始觉得上面的写法太复杂了,每次为了实现一个algorithm算法,都要重新去写一个类,如果每次比较的逻辑不一样,还要去实现多个类,特别是相同类的命名,这些都给编程者带来了极大的不便。因此,在C++11语法中出现了Lambda表达式
。
用法
语法
lambda表达式书写格式:[capture-list] (parameters) mutable -> return-type { statement }
捕获列表
场景一:
场景二: