来源/短篇小说/顽强的走秀
从C++98到C++11,C++11的标准沉淀了十几年。虽然更新速度越来越快,出现了C++14,C++17等等,但是C++11是一个必须要学的经典标准。
主要功能目录(加粗是为了实现以前没有的重要功能,或者真的很好用):
关键字及新语法 1.1. auto 关键字及用法 1.2. nullptr 关键字及用法 1.3. for 循环语法STL 容器 2.1. std::array 2.2. std::forward_list 2.3. std::unordered_map 2.4. std::unordered_set多线程 3.1. std::thread 3.2. std::atomic 3.3. std::condition_variable智能指针内存管理 4.1. std::shared_ptr 4.2. std::weak_ptr其他 5.1. std::function、std::bind 封装可执行对象 5.2. lambda 表达式1.关键词和新语法
1.1.自动关键字和用法
Auto并没有让C++成为弱类型语言,但是在使用auto的时候,编译器会根据上下文来确定auto变量的真实类型。
AutoAddTest(inta,intb){ // auto可以作为函数的返回值类型:return+b;} int main(){ autoindex = 10;//自动识别类型为inta utors = AddTest(1,2);STD::cout & lt;& lt索引:“& lt& lt索引<。& ltSTD::endl;//index:10st d::cout & lt;& ltRES:“& lt;& ltret <。& ltSTD::endl;// res: 3}
但是需要注意的是,当auto作为函数的返回值时,必须是用来定义函数的,而不仅仅是声明函数。
1.2.nullptr关键字和用法
nullptr出现之前存在哪些问题?首先,NULL不是关键字,只是一个宏:
#定义空0
考虑一个函数过载的情况:
void foo(int){ }/# 1 void foo(char *){ }/# 2 int main(){ foo(NULL);//呼叫#1还是#2?}
为了解决这个歧义,C++11引入了关键字nullptr作为空指针常量。foo(nullptr);函数#2将被无异议调用。
1.3.for循环语法
原来的C++ for循环没有foreach这样的用法。现在C++ 11的for循环语法结合auto关键字可以大大简化开发代码:
int main() { int numbers[] = {1,2,3,4,5 };for(自动编号:numbers)STD::cout & lt;& lt号码<。& ltSTD::endl;}
2.STL容器2.1。标准::数组
与数组相比,std::array增加了STL的各种迭代器、算法和操作方法,更加安全方便。
与std::vector相比,std::array提供了一个静态数组,它在编译时决定了数组的大小,更轻更高效,当然比std::vector有更多的局限性。
Std::array几乎是std::vector和普通数组的中性版本。
#include <。array>。int main(){ STD::array & lt;int,4 >arrayDemo = {1,2,3,4 };for(auto it:Arraydemo)STD::cout & lt;& ltit <。& ltSTD::endl;int Arraydemosize = sizeof(Arraydemo);STD::cout & lt;& lt" arrayDemo大小:" & lt& ltarrayDemoSize & lt。& ltSTD::endl;// 16返回0;}
2.2.std::forward_list
Std::forward_list是一个新的线性表,与list的区别在于它是一个单向链表。Forward_list可以看作是C语言风格的单链表的封装,只提供有限的接口。相比其在C语言中的实现,基本没有开销。与std::list相比,当不需要双向迭代时,此容器在空之间具有更高的利用率。
#include <。转发列表>int main(){ STD::forward _ list & lt;int>。numbers = {1,2,3,4,5,4,4 };for(自动编号:numbers)STD::cout & lt;& lt号码<。& lt" ";//1 2 3 4 5 4 numbers . remove(4);//移除节点STD:: cout
2.3.标准::无序映射
C++无序映射
2.4.标准::无序集
std::unordered_set的数据存储结构也是hashtable+list。另外,std::unordered_set像std::set一样插入时不会自动排序。
#include <。无序集。#include <。set>。int main(){ STD::unordered _ set & lt;int>。unorder _ setunorder _ set . insert(7);unorder _ set . insert(5);unorder _ set . insert(3);unorder _ set . insert(4);unorder _ set . insert(6);for(auto itor:unorder _ set)STD::cout & lt;& ltitor <。& lt" ";//7 5 3 4 6 STD::set & lt;int>。设置;set . insert(7);set . insert(5);set . insert(3);set . insert(4);set . insert(6);for(auto itor:set)STD::cout & lt;& ltitor <。& lt" ";// 3 4 5 6 7}
3.多线程操作
在C++11之前,C++的多线程编程依赖于系统或者第三方接口,这在一定程度上影响了代码的可移植性。C++11中引入了boost库中的部分多线程,标准接口与boost库基本不变,方便用户切换到C++标准接口。
3.1.标准::线程
C++11中的Std::thread解决了boost::thread中的参数限制问题,这可能是由于C++11中变量参数的设计风格。
线程类中有三种方法:
join:等待线程完成其执行。当 a 线程调用此方法时,主线程就被停止执行,直到 a 线程执行完毕。 detach:容许线程从线程句柄独立开来执行。当此方法被调用后,执行的线程从线程对象中分离,已不再被一个线程对象所表达。C++ 线程对象可以被销毁,同时 OS 执行的线程可以继续。 swap:交换 2 个 thread 对象。3.2. std::atomic当我们在编程中想要保护共享资源时,自然会想到锁定,但是锁定机制会大大增加时间成本。
Std::atomic是C++11包的原子数据类型。从功能的角度来看,原子数据类型可以直接用于多线程,而不需要我们的用户添加互斥的资源锁。从实现上可以理解,这些原子类型是自己锁定的。
在以下示例中,我们使用100个线程来模拟10,000次页面点击:
#include <。原子的。#include <。thread>。#include <。iostream>。#include <。列表>。//使用原子数据类型作为共享资源的数据类型STD::atomic _ int total(0);//long total = 0;void click(){ for(int I = 0;i<。100;++i) //只是数据类型的不同,它的访问形式和普通数据类型的资源没有什么区别。total+= 1;}int main(){ //创建100个线程模拟点击统计STD:: list
3.3.标准::条件变量
多线程编程中经常用到线程休眠,经常需要等待一些异步执行条件的返回结果。当调用std::condition_variable对象的等待函数时,它使用std::unique_lock(通过std::mutex)来锁定当前线程。当前线程将被阻塞,直到另一个线程调用同一个std::condition_variable对象上的通知函数来唤醒当前线程。
#include <。iostream>。//STD::cout # include & lt;thread>。//STD::thread # include & lt;mutex>。// std::mutex,STD::unique _ lock # include & lt;条件变量>。//STD::condition _ variabletd::mutex MTX;//全局互斥STD::condition _ variable cv;//全局条件变量bool ready = false//全局标志void do _ print _ id(int id){ STD::unique _ lock
输出结果(顺序不确定):
10个线程准备比赛...线程9线程2线程3线程8线程7线程6线程5线程4线程1线程0
4.智能指针内存管理
智能指针及其作用
简单画出指针、智能指针对象和计数器之间的关系:
5.其他5.1。std::function,std::bind包可执行对象
Std::bind用于绑定可调用对象及其参数。绑定后可以用std::函数保存,延迟到我们需要调用:
将可调用对象与其参数绑定成一个仿函数;可绑定部分参数。绑定某些参数时,使用std::占位符来决定调用发生时空位将是哪个参数。
#include <。iostream>。//STD::cout # include & lt;功能性>。//STD::function class A { public:int I _ = 0;// C++11允许非静态数据成员在它们的声明中初始化(在它们的类中)。无效输出(int x,int y) {STD:: cout
5.2.λ表达式
Lambda表达式用于定义和创建匿名函数对象,以简化编程。它可以用作内联函数。lambda的语法如下:
[...] (...)...{...}
[] 内是一个 capture,可以在 lambda 内部访问的"nonstatic 外部变量",如果没有要访问的变量,可以为空。static 变量是可以直接被访问的。() 内是参数,和函数参数一样。... 是 mutable 或 exception 声明或者返回类型。如果其中之一出现,那么必须出现 ()。{} 内是函数体,在这里面写明 lambda 要完成的工作。int main(){ int XXX = 10;auto f =[XXX](int a){ cout & lt;& lt你好,世界。& lta <。& ltxxx <。& ltendl};f(12);返回0;}
-结束-
转载声明:本文选自《简书》。点击链接阅读原文注意。
1.《std C++11 新特性》援引自互联网,旨在传递更多网络信息知识,仅代表作者本人观点,与本网站无关,侵删请联系页脚下方联系方式。
2.《std C++11 新特性》仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证。
3.文章转载时请保留本站内容来源地址,https://www.lu-xu.com/caijing/1525521.html