一.智能指针
1.std::shared_ptr
shared_ptr使用了引用计数,每一个shared_ptr的拷贝都指向相同的内存,每次拷贝都会触发引用计数+1,每次生命周期结束析构的时候引用计数-1,在最后一个shared_ptr析构的时候,内存才会释放。
2.std::weak_ptr
weak_ptr是用来监视shared_ptr的生命周期,它不管理shared_ptr内部的指针,它的拷贝的析构都不会影响引用计数,纯粹是作为一个旁观者监视shared_ptr中管理的资源是否存在,可以用来返回this指针和解决循环引用问题。
3.std::unique_ptr
unique_ptr是一个独占型的智能指针,它不允许其它智能指针共享其内部指针,也不允许unique_ptr的拷贝和赋值。使用方法和shared_ptr类似,区别是不可以拷贝。
二.类型推导
1.auto
让编译器在编译器就推导出变量的类型,可以通过=右边的类型推导出变量的类型。
2.decltype
相对于auto用于推导变量类型,而decltype则用于推导表达式类型,这里只用于编译器分析表达式的类型,表达式实际不会进行运算。
三.右值引用
-
左值:可以取地址并且有名字的东西就是左值。
-
右值:不能取地址的没有名字的东西就是右值。
-
纯右值:运算表达式产生的临时变量、不和对象关联的原始字面量、非引用返回的临时变量、lambda表达式等都是纯右值。
-
将亡值:可以理解为即将要销毁的值。
-
左值引用:对左值进行引用的类型。
-
右值引用:对右值进行引用的类型。
-
移动语义:转移资源所有权,类似于转让或者资源窃取的意思,对于那块资源,转为自己所拥有,别人不再拥有也不会再使用。
-
完美转发:可以写一个接受任意实参的函数模板,并转发到其它函数,目标函数会收到与转发函数完全相同的实参,通过std::forward()实现。
-
返回值优化:当函数需要返回一个对象实例时候,就会创建一个临时对象并通过复制构造函数将目标对象复制到临时对象,这里有复制构造函数和析构函数会被多余的调用到,有代价,而通过返回值优化,C++标准允许省略调用这些复制构造函数。
四.范围for循环
for循环基于范围的迭代写法,for(变量:对象)表达式
vector<int> vec;
for (int i : vec) { // c++11基于范围的for循环
cout << "i" << endl; }
五.nullptr
c++11用来表示空指针新引入的常量值,在c++中如果表示空指针语义时建议使用nullptr而不要使用NULL,因为NULL本质上是个int型的0,不同的编译器对其定义不同,有的定义为((void*)0),有的定义为0,所以可能会有二义性。
六.并发
1.std::thread
thread t(func);//创建一个线程t,执行func函数。
这里需要注意的是,如果线程对象t生命周期结束调用析构函数清理资源,但是线程函数func还没有执行完,则运行时会崩溃。这里有两种解决办法,一个是调用join(),保证线程函数的生命周期和线程对象的生命周期相同,另一个是调用detach(),将线程和线程对象分离,这里需要注意,如果线程已经和对象分离,那我们就再也无法控制线程什么时候结束了,不能再通过join来等待线程执行完。
2.lock_guard
是⼀个互斥量包装程序,它提供了⼀种⽅便的RAII(Resource acquisition is initialization )风格的机制来在作⽤域块的持续时间内拥有⼀个互斥量。创建lockguard对象时,它将尝试获取提供给它的互斥锁的所有权。当控制流离开lockguard对象的作⽤域时,lock_guard析构并释放互斥量。
3.unique_lock
lockguard 的升级加强版,它具有 lock_guard 的所有功能,同时又具有其他很多方法,相比于std::unique_lock更加轻量级,少了一些成员函数,std::unique_lock类有unlock函数,可以手动释放锁,所以条件变量都配合std::unique_lock使用,而不是std::lock_guard,因为条件变量在wait时需要有手动释放锁的能力
七.lambda表达式
语法格式为
auto func = [capture](params) opt -> return {func_body;};
其中func可以当作lambda表达式的名字,作为一个函数使用,capture是捕获列表,params是参数表,opt是函数选项(mutable之类), ret是返回值类型,func_body是函数体,只有capture和{func_body}是必选的。一个完整的lambda表达式如下:
auto func1 = [](int a) -> int { return a + 1; };
auto func2 = [](int a) { return a + 2; };
lambda表达式允许捕获一定范围内的变量:
- []不捕获任何变量
- [&]引用捕获,捕获外部作用域所有变量,在函数体内当作引用使用
- [=]值捕获,捕获外部作用域所有变量,在函数内内有个副本使用
- [=, &a]值捕获外部作用域所有变量,按引用捕获a变量
- [a]只值捕获a变量,不捕获其它变量
- [this]捕获当前类中的this指针
还可以使用lambda表达式自定义stl的规则。
八.列表初始化
直接在变量名后面加上初始化列表来进行对象的初始化。
struct A {
public:
A(int) {}
private:
A(const A&) {}
};
int main() {
A a(123);
A b = 123; // error
A c = { 123 }; A d{123}; // c++11
int e = {123};
int f{123}; // c++11 return 0; }
标签:11,std,变量,int,特性,线程,C++,ptr,函数 From: https://www.cnblogs.com/lhiker/p/17592716.html