本文共 6156 字,大约阅读时间需要 20 分钟。
//编译器能通过上下文,推断出auto变量的类型auto fun(int a,int b){ return a + b;}int main(){ auto a = 10; auto c = 'c'; auto str = "qwe"; return 0;}
在c++ 14中auto 可以作为函数的返回值;
auto可以用于定义函数,不能用于声明函数,例如:class Test{ public: //会发生变异时的错误 auto TestWork(int a ,int b);};
class Test{ public: Test(int index) { cout << "Test(int)" << endl; } Test(void *ptr) { cout << "Test(void *ptr)" << endl; }};int main(){ Test(NULL); //NULL 是宏定义,代表整形值0 Test(nullptr);}
int main(){ vector vec; for(int i = 0; i < 10; i++) { vec.push_back(rand()); } //内部迭代器实现 for(auto val:vec) { cout << val << " "; } cout << endl; return 0;}
int main(){ //用法与普通的数组基本一样, //在底层封装了迭代器 arrayarr = { 1,2,3,4}; for(auto val:arr) { cout << val << " "; } cout << endl; int size = sizeof(arr); cout << "数组的字节数" << size << endl;}
与list 一样都是链式结构,list 采用的是双向链表,forward_list 采用的是单向链表
int main(){ //用法与list 的用法一样 forward_list ls; for(int i = 0; i < 10; i++) { ls.push_front(rand()); } for(auto val:ls) { cout << val << " "; } cout <
使用方法与map 类似,只是底层实现的数据结构不一样,map set 基于红黑树
unordered_map 与unordered_set底层实现的数据结构是哈希表,所以在选择容器的时候,如果对数据的有序性有要求,则选择map 或则 set ;如果对有序性没有要求,则选择unordered_map 或者 ubordered_set,因为哈希表的增删查的时间复杂度都接近于O(1int main(){ srand(time(0)); unordered_mapma; for(int i = 0; i < 100; i++) { ma[rand() % 10 + 1]++; } for(auto val:ma) { cout << val.first << "==>" << val.second << endl; } return 0;}
void threadfun1(){ cout << "threadfun1()" << endl; this_thread::sleep_for(chrono::seconds(1)); cout << "threadfun1() over" << endl;}void threadfun2(int a,string str){ cout << a << " == >" << str << endl; cout << "threadfun2()" << endl; this_thread::sleep_for(chrono::seconds(5)); cout << "threadfun2() over" << endl;}int main(){ //线程执行threadfun1函数 thread t1(threadfun1); //线程执行threadfun2函数 thread t2(threadfun2,10,"abc"); //主线程等待线程的结束 t1.join(); cout << "t1.join()" << endl; //不等待现成的结束。 t2.detach(); cout << "t2.detach()" << endl; return 0;}
atomic 为c++11 封装了原子数据类型。
从功能上看,简单地说,原子数据类型不会发生数据竞争,能直接用在多线程中而不必我们用户对其进行添加互斥资源锁的类型。从实现上,大家可以理解为这些原子类型内部自己加了锁。atomic_int iCount;void threadfun(){ for(int i = 0; i < 10000; i++) { iCount++; }}int main(){ vectorvec; for(int i = 0; i < 10; i++) { vec.push_back(thread(threadfun)); } for(auto &val:vec) { val.join(); }}
C++11中的std::condition_variable就像Linux下使用pthread_cond_wait和pthread_cond_signal一样,可以让线程休眠,直到被唤醒,再从新执行。线程等待在多线程编程中使用非常频繁,经常需要等待一些异步执行的条件的返回结果。
mutex mu;condition_variable cv;bool ready = false;void threadfun(int id){ cout << id << "已经到达" << endl; while(!ready) { unique_locklck(mu); //阻塞线程直到ready为true为止 cv.wait(lck); }}void go(){ unique_lock lck(mu); ready = true; //唤醒所以线程 cv.notify_all();}int main(){ vector vec; for(int i = 0; i < 10; ++i) { vec.push_back(thread(threadfun,i)); } cout << "all threads ready" << endl; go(); for(auto &val:vec) { val.join(); } return 0;}
带引用计数的的智能指针,也叫强引用指针
class Test{ public: Test() { cout << "Test()" << endl; } ~Test() { cout << "~Test()" << endl; }private: int *ptr;};int main(){ shared_ptrt1(new Test); //智能指针的拷贝构造时,不重新申请内存,不调用构造函数 //只是将第一次开辟的内存的引用计数加一 shared_ptr t2(t1); //输出2 cout << t1.use_count() << endl; //输出2 cout << t2.use_count() << endl; return 0;}
带引用计数的智能指针,弱引用计数
class Test{ public: Test() { cout << "Test()" << endl; } ~Test() { cout << "~Test()" << endl; }private: int *ptr;};int main(){ shared_ptrt1(new Test); //智能指针的拷贝构造时,不重新申请内存,不调用构造函数 //内存的引用计数不变,强引用指针的观察者数量加一 weak_ptr t2(t1); //输出1 cout << t1.use_count() << endl; //输出1 cout << t2.use_count() << endl; return 0;}
class B;class A{ public: A() { cout << "A()" << endl; } ~A() { cout << "~A()" << endl; } shared_ptr ptr_b;};class B{ public: B() { cout << "B()" << endl; } ~B() { cout << "~B()" << endl; } shared_ptr ptr_a;};int main(){ shared_ptr ptra(new A); shared_ptr ptrb(new B); ptra->ptr_b = ptrb; ptrb->ptr_a = ptra; cout << ptra.use_count() << endl; cout << ptrb.use_count() << endl;}可以看到结果中调用了A B 的构造函数,但是并没有调用析构函数,说明存在内存的泄漏。产生的 原因是:
shared_ptr ptra(new A); shared_ptr ptrb(new B);
两句分别使ptra 和 ptrb 指向了新开辟的两块内存,此时两块内存的引用计数都为1,
当执行ptra->ptr_b = ptrb; ptrb->ptr_a = ptra;
的时候,两块内存的引用计数都分别加一,两块内存的引用计数都变为2,
当程序结束的时候,ptra 指针析构,内存A的引用计数变为1,不释放内存,ptrb 指针析构,内存B 的引用计数变为1,不释放内存。所以,再程序结束的时候,两块内存的引用计数并没有变为0. 解决方法:class B;class A{ public: A() { cout << "A()" << endl; } ~A() { cout << "~A()" << endl; } shared_ptr ptr_b;};class B{ public: B() { cout << "B()" << endl; } ~B() { cout << "~B()" << endl; } weak_ptr ptr_a;};int main(){ shared_ptr ptra(new A); shared_ptr ptrb(new B); ptra->ptr_b = ptrb; ptrb->ptr_a = ptra; cout << ptra.use_count() << endl; cout << ptrb.use_count() << endl;}
#include#include using namespace std;/* bind 函数的使用*/class comp{ public: bool operator()(int a,int b) { return a > b; }private:};bool func(int a,int b){ return a > b;}int main(){ //将f指向绑定后的函数函数 // 表示形参列表,返回值类型 //绑定后的结果可以通过std::function进行保存 //bind参数 函数指针,函数的参数列表 function f = bind(comp(), 1, std::placeholders::_1); //std::placeholders::_2 表示占位符,表示实参的第二个放到该位置, cout << bind(func, std::placeholders::_2, 1)(2,-1) << endl; //调用绑定后的函数 cout << f(-1) << endl; return 0;}
//如果一个函数的要求既能接受函数指针,也能接受函数对象class Test{ public: //function 可以结合bind 使用,对bind 的函数进行保存 //也可以作为形参,不仅可以接受函数指针,还可以接受函数对象 int Add(functionf,int a,int b) { return f(a,b); }};int main(){ //类似于函数指针的用法 void func(int); funtion f = func; return 0;}
lambda的声明方式
[capture list] (params list) mutable exception-> return type { function body }各项具体含义如下1、capture list:捕获外部变量列表2、params list:形参列表3、mutable指示符:用来说用是否可以修改捕获的变量4、exception:异常设定5、return type:返回类型6、function body:函数体
此外还有几种简写的方式
capture list:捕获外部变量列表转载地址:http://zxnwi.baihongyu.com/