C++11常用新特性使用经验总结
转载请注明 作者:源码先生, 文章链接:https://www.debugself.com/2017/10/12/cpp11/, 请勿用于商业用途
更方便的就地初始化
在定义类成员变量时直接初始化,如下:
1 | class Device{ |
是不是非常方便?妈妈再也不用担心我的变量忘记初始化了
另外,还可以直接初始化结构体成员:
1 | typedef struct _Channel{ |
也可以直接初始化类中的结构体成员
1 | class Device{ |
也可以直接初始化各种STL容器
1 | vector<int> vec = {1,2,3}; |
上面的例子中,初始化vector等容器的元素的个数是不固定的,这个如何做到的呢?有兴趣的话可以进一步研究初始化列表std::initializer_list,使用std::initializer_list可以初始化自定义的类型,这样就可以用多个个数不固定的元素,来初始化自定义类型。
auto关键字:自动推导变量类型
下面的代码
1 | map<string,int>::iterator it = m.find("debug"); |
可以简化为
1 | auto it = find("debug"); |
烦人的长串map<string,int>::iterator终于可以拜拜了
当然C++的是强类型语言,所以并不存在auto这种类型,变量it在编译时期被编译器自动推导为真正的类型,it的类型依旧是map<string,int>::iterator
更方便的for循环
使用新的for特性,可以更方便遍历数组或者各种容器中的元素
1 | int array\[10\]{0,1,2,3,4,5,6,7,8,9}; |
当需要修改容器中的元素时,请用下面的方式:
vector
for(auto &it:vec)it++;
注意,for(auto it:vec)中的it是一个元素的副本,当产生副本比较耗时间或者耗空间时,请使用for(auto &it:vec)的方式,而不是使用for(auto it:vec)的方式
tuple元组
元组类似具有多列的记录,举例,保存人员信息时,先定义如下结构体
1 | typedef struct _Person{ |
修改为使用tuple,可以如下定义
1 | typedef tuple<int,string,int> Person; |
操作元组
1 | Person person = make_tuple(1, "DebugSelf", 18); // 构造元组 |
nullptr关键字:更安全的空指针
C++中使用NULL表示空指针,而NULL的定义如下
1 | #define NULL 0 |
因为NULL实质是0,当遇到如下的重载函数时
1 | void fun(int a, int b); |
我们的本意是想调用第二个fun,但是因为NULL本质是0,最终调用的是第一个fun;
C++新增nullptr关键字,用来表示空指针,他的类型就是指针,而不是int类型的0,调用fun(a,nullptr)会正确调用第二个fun。
为了代码更安全,请使用nullptr代替NULL。
新增类型转换函数std::to_string
在C++11之前,要想把int转换为string,需要
1 | int value=10; |
每次写这段转换代码时,心里都在暗骂,MD这个功能不应该是标准库自带的吗?C++11后终于引入了to_string把int转换为string,上述代码简化为:
1 | string str=to_string(value); |
to_string其实功能还比较弱,连转换格式控制都不提供,不过总比没有强吧,汗。
另外,std::stoi/stol/stoll是把string转换为数值。
更方便更安全的智能指针shared_ptr
见《C++11智能指针shared_ptr、weak_ptr、unique_ptr用法详解》
更方便的函数:lambda表达式
使用lambda可以就地创建一个函数,写法更简洁,提高了编码效率
功能更强的回调函数:function和bind
效率更高的右值引用
见《C++11 右值引用、 move、emplace、emplace_back原理和用法详解》
for_each
使用for_each,可以针对容器中的元素,依次调用指定的函数
1 | void print(int& elem) { |
原始字符串R”()”
原始字符串中,是不存在字符转义的问题的,比如Windows上文件路径C:\Users\debugself\Desktop\notepad2\Notepad2.txt要写在代码中,需要写成
1 | string path=“C:\\\Users\\\debugself\\\Desktop\\\notepad2\\\Notepad2.txt”; |
使用原始字符,就可以直接写为
1 | string path=R“(C:\\Users\\debugself\\Desktop\\notepad2\\Notepad2.txt)”; |
新增无序容器
unordered_map/unordered_multimap、unordered_set/unordered_multiset
无序容器,内部通过Hash Table实现,比map和set的红黑树效率更高
mutable关键字:突破const关键字的限制
其他
- C++11还引入了很多操作系统相关的库,如:
- 线程:线程这个很方便,可以跨平台,而且比CreateThread、pthread都简洁方便
- 处理日期和时间的chrono库,包括计时器timer,记录时长duration
- regular expression:正则表达式
- 变参数模板:STL库的实现很多都基于可变参数模板实现的。C++11大量使用了模板各种奇淫技巧,模板的用法真是无穷无尽,有了模板的存在,谁还敢说精通C++?。
其实C++11中新引入的功能,之前boost库已经早实现过了(所以大家都叫boost为准标准库,哈哈),boost烦人的地方就是库太大,版本太多,部分模块必须编译为共享库才能使用,每次使用boost都得附加一堆文件,现在好了,直接使用C++11吧。
参考资料