本文介绍c++11标准部分内容(面试重点部分)
1.所有STL容器支持列表初始化。
std::vector v = { 1, 2, 3 };
2.auto关键字。
编译器可以根据初始值自动推导出类型。但是不能用于函数传参以及数组类型的推导
3.范围遍历,对容器。
for(auto item : vec) {};
4.nullptr出现。
空指针,可转化为其他任意指针类型。NULL被宏定义为0,遇到函数重载时可能会有问题
5.lambda表达式
一个lambda表达式表示一个可调用的代码单元,可理解为一个未命名的内联函数。与函数不同,lambda可定义在函数内部;必须以尾置返回来指定返回类型;lambda不能有默认参数,即一个lambda调用的实参数目与形参数目相同。
[capture list] (parameter list) -> return type {function body}
[=]值捕获 [&]引用捕获
auto add = [](int a, int b) { return a + b; };
std::cout << add(1, 2) << std::endl;
6.右值引用+移动语义(move)
右值:C++中,左值通常指可以取地址,有名字的值就是左值,而不能取地址,没有名字的就是右值。而在指C++11中,右值是由两个概念构成,将亡值和纯右值。纯右值是用于识别临时变量和一些不跟对象关联的值,比如1+3产生的临时变量值,而将亡值通常是指具有转移语义的对象,比如返回右值引用T&&的函数返回值等。
C++11中,右值引用就是对一个右值进行引用的类型。由于右值通常不具有名字,所以我们一般只能通过右值表达式获得其引用,比如:T && a=ReturnRvale();
假设ReturnRvalue()函数返回一个右值,那么上述语句声明了一个名为a的右值引用,其值等于ReturnRvalue函数返回的临时变量的值。
基于右值引用可以实现移动(转移)语义和完美转发新特性。
移动语义:
对一个有指针变量的类,对其进行拷贝时默认是浅拷贝,一般需要实现有拷贝构造函数的深拷贝,为指针成员分配新内存。
然而在很多情况下,使用这样的类对象作为临时对象返回时会经历多次拷贝,不断地申请和释放内存,影响性能。此时,使用移动构造函数,接收一个右值作为参数,避免分配内存,提高性能
class test{
public:
test() : i(new int(0)) {}
test(const test& r) : i(new int(*(r.i))) {}
~test() {}
private:
int* i;
};
test fun() { return test(); }
int main() {
test a = fun(); //一次构造函数,两次拷贝构造函数
return 0;
}
增加移动构造函数:
test(test&& r) : i(r.i) { r.i = nullptr;}
完美转发:
完美转发是指在函数模板中,完全依照模板的参数的类型,将参数传递给函数模板中调用的另一个函数,即传入转发函数的是左值对象,目标函数就能获得左值对象,转发函数是右值对象,目标函数就能获得右值对象,而不产生额外的开销。
因此转发函数和目标函数参数一般采用引用类型,从而避免拷贝的开销。其次,由于目标函数可能需要能够既接受左值引用,又接受右值引用,所以考虑转发也需要兼容这两种类型。
根据引用折叠规则,我们将转发函数和目标函数的参数都设置为右值引用类型。
7.智能指针
关于智能指针可见另一篇博客
https://blog.youkuaiyun.com/sunximei/article/details/119718946