目录
1.类型推导
2.范围for
3.nullptr
4.内置类型的成员变量在类中声明时可以直接在类中初始阿化
5.列表初始化
6.可变模板参数列表
7.STL中新增加容器
8.final 和 override
9.默认成员函数的控制
10.智能指针
11.右值引用
12.lambda表达式
13.线程库
auto decltype
nullptr:空值指针
{}的方式初始化
用户自定义类型单个对象直接支持{}的初初始化,如果一段空间的初始化--{}initializer_list
序列式容器 array:静态类型顺序表 forward_list:带头结点单向循环链表
关联式容器 底层为哈希结构 unordered_map/set/...
final 修饰类:该类不能被继承 修饰虚函数:最好修饰子类的虚函数---作用:该虚函数不能被其子类再重写
override:只能修饰子类的虚函数,作用:让编译器在编译阶段检测该函数释放重写了基类的某个虚函数
=default:跟在默认成员函数参数列表之后,作用:告诉编译器在编译阶段生成该默认的成员函数
=delete:根再默认成员函数参数列表之后,作用:告诉编译器在编译阶段删除该默认成员函数
实现智能指针时需要考虑以下三个方面的问题:
在对象构造时获取资源,在对象析构的时候释放资源,利用对象的生命周期来控制程序资源,即RAII特性。
对*和->运算符进行重载,使得该对象具有像指针一样的行为。
智能指针对象的拷贝问题。
概念说明: RAII(Resource Acquisition Is Initialization)是一种利用对象生命周期来控制程序资源(如内存、文件句柄、互斥量等等)的简单技术。
2. RAII: 资源获取即初始阿化---构造函数中放置资源,析构函数中销毁资源----在创建对象时编译器会自动调用构造函数和虚构函数
实现原理:RAII:保证资源自动释放 具有指针的操作:T& operator*() 和 T* operator->()重载 解决浅拷贝的方式
各种不同版本的智能指针:
auto_ptr C++98: 资源转移 C++11之前:资源管理权限的转移----对资源释放的权限 C++11:又恢复到---资源转移
unique_ptr 资源独占---从跟上防止浅拷贝:将拷贝构造和赋值运算符重载禁止 优点:实现简单,效率高 缺陷:不能共享
shared_ptr 可以共享,原理:引入引用计数---使用资源的对象的个数 优点:可能共享
缺点:实现复杂 考虑线程安全 效率第 循环引用
weak_ptr 不能单独管理对象,唯一作用:就是配合shared_ptr解决循环问题
左值是一个表示数据的表达式,如变量名或解引用的指针。
右值也是一个表示数据的表达式,如字母常量、表达式的返回值、函数的返回值(不能是左值引用返回)等等。
传统的C++语法中就有引用的语法,而C++11中新增了右值引用的语法特性,为了进行区分,于是将C++11之前的引用就叫做左值引用。但是无论左值引用还是右值引用,本质都是给对象取别名。
左值引用就是对左值的引用,给左值取别名,通过“&”来声明。
右值引用就是对右值的引用,给右值取别名,通过“&&”来声明。
右值是不能取地址的,但是给右值取别名后,会导致右值被存储到特定位置,这时这个右值可以被取到地址,并且可以被修改,如果不想让被引用的右值被修改,可以用const修饰右值引用。
左值引用不能引用右值,因为这涉及权限放大的问题,右值是不能被修改的,而左值引用是可以修改。
但是const左值引用可以引用右值,因为const左值引用能够保证被引用的数据不会被修改。
因此const左值引用既可以引用左值,也可以引用右值
右值引用只能引用右值,不能引用左值。
但是右值引用可以引用move以后的左值。
move函数是C++11标准提供的一个函数,被move后的左值能够赋值给右值引用
移动语义:借助String类分析operator+的实现的缺陷 指的是:资源转移---将将亡对象中的资源转移给其他对象
移动构造 T(T&& t)
{}
移动赋值 T& operator=(T&& t)
{}
完美转发
语法格式:[捕获列表](参数列表)mutable->返回值类型{ .... }
[]必须要有,不能省略
如果没有参数,参数列表可以省略
mutable可以省略
->返回值类型可以省略
{...}不能省略
[]{}最简单的lambda表达式
捕获列表:作用:捕获lambda表达式父作用域中的变量,可以在lambda表达式内部使用
捕获方式 [a,b]: 以值的方式捕获父作用域中的a和b [=]: 以值的方式捕获父作用域中的所有变量 [&a,&b]: 以引用的方式捕获父作用域中的a和b [&]: 以引用的方式捕获父作用域中的所有变量 [=,&b]: 以值的方式捕获父作用域中的所有变量,但是b以引用的方式捕获 不能重复捕获 [=,a] 或者[&, &a]属于重复捕获,编译失败
使用场景 之前需要传递函数指针的场景 或者 需要传递仿函数对象的场景,都可以采用lambda表达式来取代 sort(v.begin(), v.end(), [](int a, int b){ return a > b;});
底层实现方式:在代码层面实现的lambda表达式经过编译器编译之后将其转换为仿函数---捕获列表式中的内容实际就是该类的成员变量,lambda表达式实现体最终变成了类中的operator()的重载
thread类
创建线程方式,线程函数的实现传递的方式 函数指针 仿函数 lambda表达式
线程函数如果需要以引用的方式传参,在传参时候必须使用std::ref(参数)
原子类型 所有的内置类型都有对应的原子类型 int--->atomic_int 自定义类型也可以通过atomic模板设置为原子类型
lock_guard 和 unique_lock区别