來(lái)源/短篇小說(shuō)/頑強(qiáng)的走秀
從C++98到C++11,C++11的標(biāo)準(zhǔn)沉淀了十幾年。雖然更新速度越來(lái)越快,出現(xiàn)了C++14,C++17等等,但是C++11是一個(gè)必須要學(xué)的經(jīng)典標(biāo)準(zhǔn)。
主要功能目錄(加粗是為了實(shí)現(xiàn)以前沒(méi)有的重要功能,或者真的很好用):
關(guān)鍵字及新語(yǔ)法 1.1. auto 關(guān)鍵字及用法 1.2. nullptr 關(guān)鍵字及用法 1.3. for 循環(huán)語(yǔ)法STL 容器 2.1. std::array 2.2. std::forward_list 2.3. std::unordered_map 2.4. std::unordered_set多線(xiàn)程 3.1. std::thread 3.2. std::atomic 3.3. std::condition_variable智能指針內(nèi)存管理 4.1. std::shared_ptr 4.2. std::weak_ptr其他 5.1. std::function、std::bind 封裝可執(zhí)行對(duì)象 5.2. lambda 表達(dá)式1.關(guān)鍵詞和新語(yǔ)法
1.1.自動(dòng)關(guān)鍵字和用法
Auto并沒(méi)有讓C++成為弱類(lèi)型語(yǔ)言,但是在使用auto的時(shí)候,編譯器會(huì)根據(jù)上下文來(lái)確定auto變量的真實(shí)類(lèi)型。
AutoAddTest(inta,intb){ // auto可以作為函數(shù)的返回值類(lèi)型:return+b;} int main(){ autoindex = 10;//自動(dòng)識(shí)別類(lèi)型為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}
但是需要注意的是,當(dāng)auto作為函數(shù)的返回值時(shí),必須是用來(lái)定義函數(shù)的,而不僅僅是聲明函數(shù)。
1.2.nullptr關(guān)鍵字和用法
nullptr出現(xiàn)之前存在哪些問(wèn)題?首先,NULL不是關(guān)鍵字,只是一個(gè)宏:
#定義空0
考慮一個(gè)函數(shù)過(guò)載的情況:
void foo(int){ }/# 1 void foo(char *){ }/# 2 int main(){ foo(NULL);//呼叫#1還是#2?}
為了解決這個(gè)歧義,C++11引入了關(guān)鍵字nullptr作為空指針常量。foo(nullptr);函數(shù)#2將被無(wú)異議調(diào)用。
1.3.for循環(huán)語(yǔ)法
原來(lái)的C++ for循環(huán)沒(méi)有foreach這樣的用法。現(xiàn)在C++ 11的for循環(huán)語(yǔ)法結(jié)合auto關(guān)鍵字可以大大簡(jiǎn)化開(kāi)發(fā)代碼:
int main() { int numbers[] = {1,2,3,4,5 };for(自動(dòng)編號(hào):numbers)STD::cout & lt;& lt號(hào)碼<。& ltSTD::endl;}
2.STL容器2.1。標(biāo)準(zhǔn)::數(shù)組
與數(shù)組相比,std::array增加了STL的各種迭代器、算法和操作方法,更加安全方便。
與std::vector相比,std::array提供了一個(gè)靜態(tài)數(shù)組,它在編譯時(shí)決定了數(shù)組的大小,更輕更高效,當(dāng)然比std::vector有更多的局限性。
Std::array幾乎是std::vector和普通數(shù)組的中性版本。
#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是一個(gè)新的線(xiàn)性表,與list的區(qū)別在于它是一個(gè)單向鏈表。Forward_list可以看作是C語(yǔ)言風(fēng)格的單鏈表的封裝,只提供有限的接口。相比其在C語(yǔ)言中的實(shí)現(xiàn),基本沒(méi)有開(kāi)銷(xiāo)。與std::list相比,當(dāng)不需要雙向迭代時(shí),此容器在空之間具有更高的利用率。
#include <。轉(zhuǎn)發(fā)列表>int main(){ STD::forward _ list & lt;int>。numbers = {1,2,3,4,5,4,4 };for(自動(dòng)編號(hào):numbers)STD::cout & lt;& lt號(hào)碼<。& lt" ";//1 2 3 4 5 4 numbers . remove(4);//移除節(jié)點(diǎn)STD:: cout
2.3.標(biāo)準(zhǔn)::無(wú)序映射
C++無(wú)序映射
2.4.標(biāo)準(zhǔn)::無(wú)序集
std::unordered_set的數(shù)據(jù)存儲(chǔ)結(jié)構(gòu)也是hashtable+list。另外,std::unordered_set像std::set一樣插入時(shí)不會(huì)自動(dòng)排序。
#include <。無(wú)序集。#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>。設(shè)置;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.多線(xiàn)程操作
在C++11之前,C++的多線(xiàn)程編程依賴(lài)于系統(tǒng)或者第三方接口,這在一定程度上影響了代碼的可移植性。C++11中引入了boost庫(kù)中的部分多線(xiàn)程,標(biāo)準(zhǔn)接口與boost庫(kù)基本不變,方便用戶(hù)切換到C++標(biāo)準(zhǔn)接口。
3.1.標(biāo)準(zhǔn)::線(xiàn)程
C++11中的Std::thread解決了boost::thread中的參數(shù)限制問(wèn)題,這可能是由于C++11中變量參數(shù)的設(shè)計(jì)風(fēng)格。
線(xiàn)程類(lèi)中有三種方法:
join:等待線(xiàn)程完成其執(zhí)行。當(dāng) a 線(xiàn)程調(diào)用此方法時(shí),主線(xiàn)程就被停止執(zhí)行,直到 a 線(xiàn)程執(zhí)行完畢。 detach:容許線(xiàn)程從線(xiàn)程句柄獨(dú)立開(kāi)來(lái)執(zhí)行。當(dāng)此方法被調(diào)用后,執(zhí)行的線(xiàn)程從線(xiàn)程對(duì)象中分離,已不再被一個(gè)線(xiàn)程對(duì)象所表達(dá)。C++ 線(xiàn)程對(duì)象可以被銷(xiāo)毀,同時(shí) OS 執(zhí)行的線(xiàn)程可以繼續(xù)。 swap:交換 2 個(gè) thread 對(duì)象。3.2. std::atomic當(dāng)我們?cè)诰幊讨邢胍Wo(hù)共享資源時(shí),自然會(huì)想到鎖定,但是鎖定機(jī)制會(huì)大大增加時(shí)間成本。
Std::atomic是C++11包的原子數(shù)據(jù)類(lèi)型。從功能的角度來(lái)看,原子數(shù)據(jù)類(lèi)型可以直接用于多線(xiàn)程,而不需要我們的用戶(hù)添加互斥的資源鎖。從實(shí)現(xiàn)上可以理解,這些原子類(lèi)型是自己鎖定的。
在以下示例中,我們使用100個(gè)線(xiàn)程來(lái)模擬10,000次頁(yè)面點(diǎn)擊:
#include <。原子的。#include <。thread>。#include <。iostream>。#include <。列表>。//使用原子數(shù)據(jù)類(lèi)型作為共享資源的數(shù)據(jù)類(lèi)型STD::atomic _ int total(0);//long total = 0;void click(){ for(int I = 0;i<。100;++i) //只是數(shù)據(jù)類(lèi)型的不同,它的訪(fǎng)問(wèn)形式和普通數(shù)據(jù)類(lèi)型的資源沒(méi)有什么區(qū)別。total+= 1;}int main(){ //創(chuàng)建100個(gè)線(xiàn)程模擬點(diǎn)擊統(tǒng)計(jì)STD:: list
3.3.標(biāo)準(zhǔn)::條件變量
多線(xiàn)程編程中經(jīng)常用到線(xiàn)程休眠,經(jīng)常需要等待一些異步執(zhí)行條件的返回結(jié)果。當(dāng)調(diào)用std::condition_variable對(duì)象的等待函數(shù)時(shí),它使用std::unique_lock(通過(guò)std::mutex)來(lái)鎖定當(dāng)前線(xiàn)程。當(dāng)前線(xiàn)程將被阻塞,直到另一個(gè)線(xiàn)程調(diào)用同一個(gè)std::condition_variable對(duì)象上的通知函數(shù)來(lái)喚醒當(dāng)前線(xiàn)程。
#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//全局標(biāo)志void do _ print _ id(int id){ STD::unique _ lock
輸出結(jié)果(順序不確定):
10個(gè)線(xiàn)程準(zhǔn)備比賽...線(xiàn)程9線(xiàn)程2線(xiàn)程3線(xiàn)程8線(xiàn)程7線(xiàn)程6線(xiàn)程5線(xiàn)程4線(xiàn)程1線(xiàn)程0
4.智能指針內(nèi)存管理
智能指針及其作用
簡(jiǎn)單畫(huà)出指針、智能指針對(duì)象和計(jì)數(shù)器之間的關(guān)系:
5.其他5.1。std::function,std::bind包可執(zhí)行對(duì)象
Std::bind用于綁定可調(diào)用對(duì)象及其參數(shù)。綁定后可以用std::函數(shù)保存,延遲到我們需要調(diào)用:
將可調(diào)用對(duì)象與其參數(shù)綁定成一個(gè)仿函數(shù);可綁定部分參數(shù)。綁定某些參數(shù)時(shí),使用std::占位符來(lái)決定調(diào)用發(fā)生時(shí)空位將是哪個(gè)參數(shù)。
#include <。iostream>。//STD::cout # include & lt;功能性>。//STD::function class A { public:int I _ = 0;// C++11允許非靜態(tài)數(shù)據(jù)成員在它們的聲明中初始化(在它們的類(lèi)中)。無(wú)效輸出(int x,int y) {STD:: cout
5.2.λ表達(dá)式
Lambda表達(dá)式用于定義和創(chuàng)建匿名函數(shù)對(duì)象,以簡(jiǎn)化編程。它可以用作內(nèi)聯(lián)函數(shù)。lambda的語(yǔ)法如下:
[...] (...)...{...}
[] 內(nèi)是一個(gè) capture,可以在 lambda 內(nèi)部訪(fǎng)問(wèn)的"nonstatic 外部變量",如果沒(méi)有要訪(fǎng)問(wèn)的變量,可以為空。static 變量是可以直接被訪(fǎng)問(wèn)的。() 內(nèi)是參數(shù),和函數(shù)參數(shù)一樣。... 是 mutable 或 exception 聲明或者返回類(lèi)型。如果其中之一出現(xiàn),那么必須出現(xiàn) ()。{} 內(nèi)是函數(shù)體,在這里面寫(xiě)明 lambda 要完成的工作。int main(){ int XXX = 10;auto f =[XXX](int a){ cout & lt;& lt你好,世界。& lta <。& ltxxx <。& ltendl};f(12);返回0;}
-結(jié)束-
轉(zhuǎn)載聲明:本文選自《簡(jiǎn)書(shū)》。點(diǎn)擊鏈接閱讀原文注意。
1.《std C++11 新特性》援引自互聯(lián)網(wǎng),旨在傳遞更多網(wǎng)絡(luò)信息知識(shí),僅代表作者本人觀(guān)點(diǎn),與本網(wǎng)站無(wú)關(guān),侵刪請(qǐng)聯(lián)系頁(yè)腳下方聯(lián)系方式。
2.《std C++11 新特性》僅供讀者參考,本網(wǎng)站未對(duì)該內(nèi)容進(jìn)行證實(shí),對(duì)其原創(chuàng)性、真實(shí)性、完整性、及時(shí)性不作任何保證。
3.文章轉(zhuǎn)載時(shí)請(qǐng)保留本站內(nèi)容來(lái)源地址,http://f99ss.com/caijing/1525521.html