一、列表初始化
1.C++98中{}的初始化问题
在C++98中,允许使用花括号{}对数组元素进行统一的列表初始化值设定,比如:
但是对于一些自定义类型,就无法使用这样的方式进行初始化了,比如:
就无法通过编译,导致每次定义vector时,都需要先把vector定义出来,然后使用循环对其赋初始值,非常不便。
C++11扩大了用花括号括起的列表(初始化列表)的使用范围,使其可用于所有的内置类型和用户自定义的类型,使用初始化列表时,可以添加等号,也可以不添加,没有区别。
2.自定义类型的列表初始化
多个对象的列表初始化:
多个对象想要支持列表初始化,需要给该类(模板类)添加一个带有initializer_list类型参数的构造函数。
注意:initializer_list是系统自定义的类模板,该类模板中主要有三个方法:begin()、end()迭代器,以及获取区间中元素个数的方法size()。
#include <initializer_list>
template<class T>
class Vector {
public:
//支持多个对象列表初始化
Vector(initializer_list<T> lt)
: _capacity(lt.size())
, _size(0)
{
_arr = new T[_capacity];
for (auto e : lt) {
_arr[_size++] = e;
}
}
Vector<T>& operator=(initializer_list<T> lt) {
delete[] _arr;
_size = 0;
for (auto e : lt) {
_arr[_size++] = e;
}
return *this;
}
private:
T* _arr;
size_t _capacity;
size_t _size;
};
二、变量类型推导
1.为什么需要类型推导
在定义变量时,必须先给出变量的实际类型,编译器才允许定义,但有些情况下可能不知道变量的实际类型,或类型写起来比较复杂。
所有C++11中,可以使用auto来根据变量初始化表达式类型来推导变量的实际类型,给程序的书写提供便利。
auto详细介绍
2.decltype类型推导
2.1为什么需要decltype
auto使用的前提是:必须要对auto声明的类型进行初始化,否则编译器无法推导出auto的实际类型。但有些时候可能需要根据表达式运行完成后的结果类型进行推导,但是编译期间代码不会运行,此时auto也就无法完成推导了。
比如:
如果这样返回,结果就会出现问题,但如果能够使用加完之后的实际类型作为函数返回值类型,那么就不会出错了,但是这需要程序运行完后才能知道结果的实际类型。解决方法:
返回值类型追踪:
注意:auto并不能推导函数返回值类型,在这里只是起一个占位符作用。
2.2decltype的功能
decltype是根据表达式的实际类型推演出定义变量时所用的类型:
(1)推演表达式类型作为变量的定义类型;
(2)推演函数返回值类型;
(3)返回值类型追踪
注意:推演的过程中,并不会调用函数,都是在编译阶段完成的。
三、范围for循环
范围for详细介绍
四、final与override
final与override关键字介绍
五、智能指针
C++智能指针介绍与模拟实现
六、新增加容器
(1)静态数组array;
(2)循环单链表forward_list;
(3)unordered系列。
七、默认成员函数控制
1.显示缺省函数
在C++11中,可以在默认成员函数定义或声明时,加上=default,从而显示的指示编译器生成该函数的默认版本。用=default修饰的函数称为显示缺省函数。
2.删除默认函数
如果想要限制某些默认函数的生成:
(1)C++98中:将该函数设置为private,并且只声明不定义。
(2)C++11中:只需要在该函数声明加上=delete即可,该语法指示编译器不生成对应函数的默认版本,用=delete修饰的函数称为删除函数。
八、右值引用
C++右值引用
九、lambda表达式
C++lambda表达式