当前位置: 首页 > 科技观察

说说我常用的10个C++新特性

时间:2023-03-21 18:24:41 科技观察

上一篇介绍了C++11之后的所有新特性。在本文中,我将总结一些常用的新功能。这些新功能可以说是必须要掌握的!我不太确定其他人常用的新功能。这里我只分享我和小伙伴们常用的新功能!以下为正文:auto类型推导auto允许编译器在编译器中推导变量的类型,看代码:autoa=10;//10是int类型,可以自动推导出a是intinti=10;autob=i;//b是int类型autod=2.0;//d是double类型autof=[](){//f是什么类型?就用autoreturnstd::string("d");}用auto通过=右边的类型推导出变量的类型。什么时候使用自动?简单的类型可以不用auto,但是一些复杂的类型需要用auto,比如lambda表达式的类型,async函数的类型等,例如:autofunc=[&]{cout<<"xxx";};//你func不用auto吧,反正我不管lambda表达式是什么类型。autoasyncfunc=std::async(std::launch::async,func);智能指针C++11的新特性中主要有两个智能指针std::shared_ptr和std::unique_ptr。那么什么时候用std::shared_ptr,什么时候用std::unique_ptr呢?当归属不明确且有可能多个对象共同管理同一块内存时,使用std::shared_ptr;而std::unique_ptr强调的是排他性,即一次只能有一个对象占用这块内存,不支持多个对象共同管理同一块内存。两种类型的智能指针的使用方式类似。以std::unique_ptr为例:usingnamespacestd;structA{~A(){cout<<"Adelete"<(newA);autotptr=std::make_unique();//错误,c++11不够,需要c++14std::unique_ptrtem=ptr;//错误,unique_ptr不允许移动,编译失败ptr->Print();return0;}std::lock相关C++11提供了两种锁封装,可以通过RAIIRelease动态实现锁定资源,防止编码错误一直持有锁。这两个包是std::lock_guard和std::unique_lock,使用方法类似,看下面代码:#include#include#include#includeusingnamespacestd;std::mutexmutex_;intmain(){autofunc1=[](intk){//std::lock_guardlock(mutex_);std::unique_locklock(mutex_);for(inti=0;ilock(mutex_);while(count_>0){if(time_ms>0){cv_.wait_for(lock,std::chrono::milliseconds(time_ms));}else{cv_.wait(lock);}}}uint32_tGetCount()const{std::unique_locklock(mutex_);返回计数_;}private:std::condition_variablecv_;mutablestd::mutexmutex_;uint32_tcount_=0;};条件变量还有几个坑,可以看这篇文章:《使用条件变量的坑你知道吗》原子操作C++11提供了原子类型std::atomic,用于原子操作,使用这种方式既可以保证线程安全,又不需要使用锁进行临界区保护,对于一些普通变量特别方便,见代码:std::atomicatomicInt;atomicInt++;atomicInt--;atomicInt.store(2);intvalue=atomicInt.load();Multithreading什么是多线程这里就不介绍了。多线程最重要的新特性是std::thread的使用。它的使用也很简单,看代码:#include#includeusingnamespacestd;intmain(){autofunc=[](){for(inti=0;i<10;++i){输出<<我<<"";}cout<(a);//d是x值的概念是的,它涉及到很多知识点,这里就不介绍了。详细可以看这篇文章:《左值引用、右值引用、移动语义、完美转发,你知道的不知道的都在这里》std::function和lambda表达式是我最常用的两个特性。使用它们将使函数调用起来相当方便。使用std::function可以完全替代以往繁琐的函数指针形式。也可以和std::bind结合使用,看一段示例代码:std::functionf;//这里function的对象f的参数是int,而返回值为void#include#includestructFoo{Foo(intnum):num_(num){}voidprint_add(inti)const{std::cout<f_display=print_num;f_display(-9);//存储lambdastd::functionf_display_42=[](){print_num(42);};f_display_42();//存储到std::bind调用的结果std::functionf_display_31337=std::bind(print_num,31337);f_display_31337();//存储到成员函数调用std::functionf_add_display=&Foo::print_add;constFoofoo(314159);f_add_display(foo,1);f_add_display(314159,1);//存储到的调用数据成员访问器std::functionf_num=&Foo::num_;std::cout<<"num_:"<f_add_display2=std::bind(&Foo::print_add,foo,_1);f_add_display2(2);//存入成员函数和对象指针调用std::functionf_add_display3=std::bind(&Foo::print_add,&foo,_1);f_add_display3(3);//存储对函数对象的调用std::functionf_display_obj=PrintNum();f_display_obj(18);}从上面可以看出std::function的使用方法。当你为std::function填写合适的参数表和返回值时,它就成为可能容纳所有此类调用方法的函数包装器std::function也可以用作回调函数,或者如果你需要在中使用回调C++,必须用std::function,很方便。你可以这样使用它阅读我之前的文章?lambda表达式可以说是C++11引入的最重要的特性之一。它定义了一个匿名函数,可以捕获一定范围内的变量并在函数内部使用。一般语法如下形式:autofunc=[capture](params)opt->ret{func_body;};其中func是可以作为lambda表达式的名称,作为函数使用,capture是捕获列表,params是参数列表,opt是函数选项(可变等),ret是返回值类型,func_body是函数体。查看以下使用lambda表达式的示例:autofunc1=[](inta)->int{returna+1;};autofunc2=[](inta){returna+2;};cout<milliseconds;typedefduration秒;duration的具体模板如下:template>classduration;rep表示数值类型,用来表示Period的个数,比如int、float、double,而Period是比率类型,用来表示[以秒表示的时间单位]比如second,常用的duration有定义好,std::chrono::duration下:ratio<3600,1>:hoursratio<60,1>:minutesratio<1,1>:secondsratio<1,1000>:microsecondsratio<1,1000000>:microsecondsratio<1,1000000000>:纳秒比的具体模板如下:templateclassratio;N代表分子,D代表分母,所以ratio代表一个分数,我们可以自定义Period,比如ratio<2,1>表示单位时间为2秒。time_point表示具体时间点,如2020年5月10日10:10:10。以当前时间为例:std::chrono::time_pointNow(){returnstd::chrono::high_resolution_clock::now();}//std::chrono::high_resolution_clock是一个高精度时钟。下面会提到clocks时钟。chrono中有3种时钟:steady_clocksystem_clockhigh_resolution_clocksteady_clock的稳定时间间隔表示相对时间,相对于系统启动时的时间,无论系统时间如何变化,下次调用now()必须大于之前调用now()的值,可以用来计时。system_clock表示当前系统时钟,可用于获取当前时间:intmain(){usingstd::chrono::system_clock;system_clock::time_pointtoday=system_clock::now();std::time_ttt=system_clock::to_time_t(today);std::cout<<"todayis:"<