C++的最后一道坎|百万年薪的程序员
?
?
| 導(dǎo)語?C++ 的起源可以追溯到 40 年前,但它仍然是當(dāng)今使用最廣泛的編程語言之一,C++發(fā)明人Bjarne Stroustrup 一開始沒想到 C++ 會(huì)獲得如此大的成功,他說:“C++ 的成功顯然令人驚訝。我認(rèn)為它的成功取決于其最初的設(shè)計(jì)目標(biāo),就是有效的使用硬件,再加上強(qiáng)大的抽象機(jī)制,以及它根據(jù)來自實(shí)際使用情況的反饋進(jìn)行謹(jǐn)慎的發(fā)展”。
?
大家好,我是Alex(艾利克斯),這是C++三部曲的最后一部,但應(yīng)該排在第一。
C++三部曲之二:C++內(nèi)存管理全景指南
C++三部曲之三:C++模版的本質(zhì)
?
?
目錄
?
?
?
C++歷史背景
?
C ++編程語言的歷史可以追溯到1979年,當(dāng)時(shí)Bjarne Stroustrup為博士學(xué)位論文進(jìn)行了一些開發(fā)。在Stroustrup可以使用的所有單詞中,有一種被稱為Simula的語言,顧名思義,它可能是一種主要為仿真而設(shè)計(jì)的語言。Simula 67語言是Stroustrup使用的變體,被認(rèn)為是支持面向?qū)ο缶幊谭独闹饕Z言。Stroustrup發(fā)現(xiàn)這種范例對(duì)包裝開發(fā)很有幫助。但是,Simula語言對(duì)于實(shí)踐和實(shí)際使用而言太慢了;
?
隨后不久,Bjarne Stroustrup希望通過支持面向?qū)ο蠓独齺碓鰪?qiáng)C。他深入研究了Smalltalk的OO實(shí)現(xiàn),以獲取有關(guān)實(shí)現(xiàn)的想法。但是他不愿意為此放棄性能,因此他開始從事“C with Classes (帶有類的C)?”的工作,希望C ++代碼運(yùn)行時(shí)應(yīng)具有與C代碼相似(或更好)的性能。
?
第一個(gè)帶有類別編譯器的C稱為Cfront,它是從稱為CPre的C編譯器派生而來的。它曾經(jīng)是一個(gè)旨在將帶有類別代碼的C轉(zhuǎn)換為通用C的程序。值得注意的目的是Cfront主要是用C用類編寫的,從而創(chuàng)建了一個(gè)自舉的編譯器(可以自行編譯的編譯器) 。Cfront后來在1993年被放棄,但是Cfront對(duì)未來的編譯器和Unix操作系統(tǒng)的實(shí)現(xiàn)產(chǎn)生了巨大影響。
?
1983年,語言的名稱從“帶有類的C”更改為C ++。C語言中的++運(yùn)算符是用于遞增變量的運(yùn)算符,它使您可以深入了解Stroustrup如何看待該語言。在此期間添加了許多新功能,其中最引人注目的是虛函數(shù),函數(shù)重載,帶有&符號(hào)的引用,const關(guān)鍵字和使用兩個(gè)正斜杠的單行注釋。
?
1985年,Stroustrup引用了名為“ C ++編程語言”的語言。已出版。同年,C ++被實(shí)現(xiàn)為商業(yè)產(chǎn)品。該語言尚未正式標(biāo)準(zhǔn)化,因此使該書成為非常重要的參考。該語言在1989年再次進(jìn)行了更新,以包括受保護(hù)的成員和靜態(tài)成員,以及從多個(gè)類的繼承.
?
1990年,發(fā)行了《帶注釋的C ++參考手冊(cè)》。同年,Borland的Turbo C ++編譯器將作為商業(yè)產(chǎn)品發(fā)布。Turbo C ++添加了許多其他庫,這些庫會(huì)對(duì)C ++的開發(fā)產(chǎn)生相當(dāng)大的影響。盡管Turbo C ++的最后一個(gè)穩(wěn)定版本是2006年,但該編譯器仍被廣泛使用。
?
1998年,C ++標(biāo)準(zhǔn)委員會(huì)發(fā)布了第一個(gè)C ++ ISO / IEC 14882:1998國際標(biāo)準(zhǔn),其非正式名稱為C ++ 98。據(jù)說《帶注釋的C ++參考手冊(cè)》對(duì)標(biāo)準(zhǔn)的制定產(chǎn)生了很大的影響。還包括標(biāo)準(zhǔn)模板庫,該模板庫于1979年開始概念開發(fā)。2003年,該委員會(huì)對(duì)1998年標(biāo)準(zhǔn)所報(bào)告的多個(gè)問題做出了回應(yīng),并對(duì)其進(jìn)行了相應(yīng)的修訂。更改的語言稱為C ++ 03。
?
2005年,C ++標(biāo)準(zhǔn)委員會(huì)發(fā)布了一份技術(shù)報(bào)告(稱為TR1),詳細(xì)介紹了他們計(jì)劃添加到最新C ++標(biāo)準(zhǔn)中的各種功能。新標(biāo)準(zhǔn)被非正式地稱為C ++ 0x,因?yàn)樗型诘谝粋€(gè)十年結(jié)束之前的某個(gè)時(shí)間發(fā)布。具有諷刺意味的是,新標(biāo)準(zhǔn)要到2011年年中才會(huì)發(fā)布。直到那時(shí)為止,已經(jīng)發(fā)布了幾份技術(shù)報(bào)告,并且一些編譯器開始為新功能添加實(shí)驗(yàn)性支持。
?
2011年中,新的C ++標(biāo)準(zhǔn)(稱為C ++ 11)完成。Boost庫項(xiàng)目對(duì)新標(biāo)準(zhǔn)產(chǎn)生了重大影響,其中一些新模塊直接來自相應(yīng)的Boost庫。一些新功能包括正則表達(dá)式支持,全面的隨機(jī)化庫,新的C ++時(shí)間庫,原子支持,標(biāo)準(zhǔn)線程庫 ,一種新的for循環(huán)語法,提供的功能類似于某些其他語言中的foreach循環(huán),auto關(guān)鍵字,新的容器類,對(duì)聯(lián)合和數(shù)組初始化列表以及可變參數(shù)模板的更好支持。
?
2014年,C ++ 14(也稱為C ++ 1y)作為C++11的一個(gè)小擴(kuò)展發(fā)布,主要功能是錯(cuò)誤修復(fù)和小的改進(jìn),國際標(biāo)準(zhǔn)投票程序草案于2014年8月中完成,加強(qiáng)lambda函數(shù),constexpr和類型推導(dǎo)特性;
?
2017年,發(fā)布C++17標(biāo)準(zhǔn),C++17提供了很多東西。增強(qiáng)了核心語言和庫;
?
2020年,發(fā)布C++20標(biāo)準(zhǔn),推出了很多重量級(jí)功能,其中比較重要:
?
-
Concepts:概念改變了我們思考和編程模板的方式。它們是模板參數(shù)的語義類別。它們使您可以直接在類型系統(tǒng)中表達(dá)您的意圖。如果出了什么問題,您會(huì)收到清晰的錯(cuò)誤消息。
-
Ranges library:新的ranges庫使它可以直接在容器上執(zhí)行算法,用管道符號(hào)組成算法,并將其應(yīng)用于無限數(shù)據(jù)流。
-
Coroutines:由于協(xié)程,C ++中的異步編程成為主流。協(xié)程是協(xié)作任務(wù),事件循環(huán),無限數(shù)據(jù)流或管道的基礎(chǔ)。
-
Modules:模塊克服了頭文件的限制。他們承諾很多。例如,頭文件和源文件的分離變得和預(yù)處理器一樣過時(shí)了。最后,我們有更快的構(gòu)建時(shí)間和更輕松的構(gòu)建軟件包的方法。
-
Concurrency:
Atomic Smart Pointers,
Joining & Cancellable Threads,
The C++20 Synchronization Library,增強(qiáng)了C++并發(fā)編程能力;
?
?
? 總結(jié)一下,C++標(biāo)準(zhǔn)演進(jìn)路線如下圖:
?
?
?
?從C++發(fā)展歷史背景來看,C++產(chǎn)生的根本原因有兩點(diǎn):
-
面向?qū)ο缶幊?#xff1a;? Bjarne Stroustrup研究Simula OOP編程思想,覺得這個(gè)是應(yīng)對(duì)大型軟件開發(fā)的絕佳武器,擁有很好的現(xiàn)實(shí)抽象能力和代碼組織能力;
?
-
高性能:Bjarne Stroustrup準(zhǔn)備開發(fā)一套通信系統(tǒng),需要編寫接近硬件的低級(jí)代碼,例如內(nèi)存管理器、進(jìn)程調(diào)度器和設(shè)備驅(qū)動(dòng)程序來分離軟件組件,由于當(dāng)時(shí)計(jì)算機(jī)硬件性能限制,對(duì)軟件性能要求苛刻,廣泛使用的C語言有比較接近硬件工作的能力,所以Bjarne Stroustrup基于C語言創(chuàng)造可以面向?qū)ο缶幊痰腃++語言;
?
?
推薦學(xué)習(xí):
《An Overview of the C++ Programming Language》Bjarne Stroustrup?
《Design and Evolution of C++》Bjarne Stroustrup
?
C++面向?qū)ο缶幊?/h2>
?
?
怎么才能深刻理解面向?qū)ο笏枷?#xff1f;
?
面向?qū)ο蟪绦蛟O(shè)計(jì)的雛形,早在1960年的Simula語言中即可發(fā)現(xiàn),當(dāng)時(shí)的程序設(shè)計(jì)領(lǐng)域正面臨著一種危機(jī):在軟硬件環(huán)境逐漸復(fù)雜的情況下,軟件如何得到良好的維護(hù)?面向?qū)ο蟪绦蛟O(shè)計(jì)在某種程度上通過強(qiáng)調(diào)可重復(fù)性解決了這一問題。20世紀(jì)70年代的Smalltalk語言在面向?qū)ο蠓矫婵胺Q經(jīng)典——以至于30年后的今天依然將這一語言視為面向?qū)ο笳Z言的基礎(chǔ)。
?
?
?
維基百科:
面向?qū)ο蟪绦蛟O(shè)計(jì)(英語:Object-oriented programming,縮寫:OOP)是種具有對(duì)象概念的編程典范,同時(shí)也是一種程序開發(fā)的抽象方針。它可能包含數(shù)據(jù)、屬性、代碼與方法。對(duì)象則指的是類(class)的實(shí)例。它將對(duì)象作為程序的基本單元,將程序和數(shù)據(jù)封裝其中,以提高軟件的重用性、靈活性和擴(kuò)展性,對(duì)象里的程序可以訪問及經(jīng)常修改對(duì)象相關(guān)連的數(shù)據(jù)。在面向?qū)ο蟪绦蚓幊汤?#xff0c;計(jì)算機(jī)程序會(huì)被設(shè)計(jì)成彼此相關(guān)的對(duì)象。
?
?
面向?qū)ο缶幊叹褪峭ㄟ^對(duì)象把現(xiàn)實(shí)世界映射到計(jì)算機(jī)模型的一種編程方法,是抽象思維的一種體現(xiàn)。而抽象是計(jì)算機(jī)科學(xué)中最重要的一種思維方式;?
?
面向?qū)ο蠓椒ǖ谋举|(zhì)就是主張從客觀世界固有的事物出發(fā)的構(gòu)造系統(tǒng),提倡用人類在現(xiàn)實(shí)生活中常用的思維方法來認(rèn)識(shí)、理解和描述客觀事物,具體實(shí)現(xiàn)采用對(duì)象為基礎(chǔ),對(duì)象是面向?qū)ο蠓椒ㄖ凶罨镜母拍睢?duì)象可以用來表示客觀世界中的任何實(shí)體,它既可以是具體的物理實(shí)體的抽象,也可以是人為的概念,或者是任何有明確邊界和意義的東西;
?
?
程序的本質(zhì)是人的意志延伸到計(jì)算機(jī)的可識(shí)別的指令。計(jì)算機(jī)(CPU)僅能識(shí)別 01代碼,本身不能解決任何問題(無意識(shí)),只能由人編寫程序控制計(jì)算機(jī)解決問題,因此編程的本質(zhì)就是人“教會(huì)”計(jì)算機(jī)解決問題。
?
?
面向?qū)ο蟮木幊碳夹g(shù)有助于減小這一隔閡、并使這兩個(gè)空間盡量趨于一致;
?
?
抽象思維一直推動(dòng)著計(jì)算機(jī)技術(shù)不斷向前發(fā)展,科學(xué)技術(shù)本身就是現(xiàn)實(shí)世界的抽象和演繹:
電路信號(hào)->01二進(jìn)制->指令匯編->高級(jí)編程->模塊設(shè)計(jì)->框架設(shè)計(jì)->單機(jī)系統(tǒng)->分布式系統(tǒng)-->云計(jì)算
推薦學(xué)習(xí):
《深入理解計(jì)算機(jī)系統(tǒng)》
《編碼:隱匿在計(jì)算機(jī)軟硬件背后的語言(美.佩措爾德)》
?
C++面向?qū)ο缶幊倘齻€(gè)核心技術(shù)
封裝
?
主要的方法是對(duì)象和類:
?
對(duì)象是面向?qū)ο蠓椒ㄖ凶罨镜母拍睢?duì)象可以用來表示客觀世界中的任何實(shí)體,它既可以是具體的物理實(shí)體的抽象,也可以是人為的概念,或者是任何有明確邊界和意義的東西;
?
類是具有共同屬性、共同方法的對(duì)象的集合,是關(guān)于對(duì)象的抽象描述,反映屬于該對(duì)象類型的所有對(duì)象的性質(zhì),它由一組靜態(tài)特征(數(shù)據(jù))和它可執(zhí)行的一組操作(方法)組成,一個(gè)對(duì)象就是類的一個(gè)實(shí)例;
對(duì)象和對(duì)象之間隱藏自己內(nèi)部實(shí)現(xiàn)細(xì)節(jié),通過標(biāo)準(zhǔn)接口進(jìn)行通信,這樣就可以提高程序內(nèi)聚,降低耦合,方便系統(tǒng)進(jìn)行解耦設(shè)計(jì),同時(shí)也提高了系統(tǒng)穩(wěn)定性,降低系統(tǒng)風(fēng)險(xiǎn)。
?
?
繼承
?
主要的方法通過類的公有繼承、保護(hù)繼承,私有繼承,單繼承,多繼承;結(jié)合類成員的三種屬性:public、protected?和?private;?來實(shí)現(xiàn)共享和限制屬性和方法的訪問;
繼承的優(yōu)點(diǎn)是:相似的對(duì)象可以共享程序代碼和數(shù)據(jù)結(jié)構(gòu),從而大大減少了程序中的冗余信息,提高軟件的可重用性,便于軟件迭代;
?
多態(tài)
?
編譯時(shí)多態(tài)
主要的方法是重載和模板,重載包括運(yùn)算符重載和函數(shù)重載,運(yùn)算符重載通過重新定義運(yùn)算符實(shí)現(xiàn)函數(shù)來實(shí)現(xiàn),底層還是函數(shù)重載,函數(shù)重載通過參數(shù)列表的不同來區(qū)分不同的方法,底層是不同的函數(shù)簽名;
模板是通過參數(shù)化類型來區(qū)分不同類和函數(shù);
細(xì)節(jié)請(qǐng)參考:
??C++模版的本質(zhì)
《C++ Templates: The Complete Guide》
?
運(yùn)行時(shí)多態(tài)
主要方法是重寫,子類對(duì)父類方法的“重新”實(shí)現(xiàn),底層是通過定義虛函數(shù)和構(gòu)建虛函數(shù)表,在虛函數(shù)表里面插入RTTI(運(yùn)行時(shí)類型信息)信息,結(jié)合繼承和動(dòng)態(tài)綁定,程序就可以根據(jù)實(shí)際類型判斷并調(diào)用相應(yīng)的屬性和方法。
?
細(xì)節(jié)請(qǐng)參考:
??C++內(nèi)存管理全景指南
《深度搜索c++對(duì)象模型》
?
多態(tài)強(qiáng)大的功能允許不修改父類代碼和業(yè)務(wù)邏輯代碼,就通過擴(kuò)展子類來實(shí)現(xiàn)功能的擴(kuò)展。多態(tài)使模塊在復(fù)用的基礎(chǔ)上具備了更強(qiáng)的可擴(kuò)展性;
?
?
C++語言核心精神
?
?
C ++的設(shè)計(jì)目標(biāo)
?
高效地使用硬件
?
-
保持與C語言兼容,C++代碼與C代碼運(yùn)行時(shí)應(yīng)具有相似(或更好)的性能;
-
將內(nèi)置操作和類型直接映射到硬件,以提供有效的內(nèi)存使用和有效的低級(jí)操作;
?
零成本的抽象機(jī)制
-
低成本的靈活抽象機(jī)制,可為用戶定義的類型提供與內(nèi)置類型相同的符號(hào)支持,用途范圍和性能;
-
類,繼承,模板,概念,別名等;
?
?
任何違反以上兩個(gè)設(shè)計(jì)目標(biāo)之一的建議都可能會(huì)遭到拒絕;
?
?
C ++的未來目標(biāo)
?
更加靈活,支持多種編程范型:
-
面向過程編程:兼容C語言編程,支持自上而下面向過程編程;
-
面向?qū)ο缶幊?#xff1a;封裝,繼承,多態(tài),對(duì)象內(nèi)存模型,構(gòu)造和析構(gòu);
-
泛型編程:泛型編程是自 STL(標(biāo)準(zhǔn)模板庫)納入到 C++ 標(biāo)準(zhǔn)以后才逐漸流行起來的新范式,核心思想是“一切皆為類型”,或者說是“參數(shù)化類型”“類型擦除”,使用模板而不是繼承的方式來復(fù)用代碼,所以運(yùn)行效率更高,代碼也更簡潔;
-
模板元編程:模板元編程是一種高級(jí)、復(fù)雜的技術(shù),C++模板是圖靈完備的,可以在編譯期間模擬一個(gè)完整的圖靈機(jī),也就是說,可以完成任何的計(jì)算任務(wù),比如編譯期數(shù)值計(jì)算、類型計(jì)算、代碼計(jì)算(如循環(huán)展開),而類型計(jì)算和代碼計(jì)算可以使得代碼更加通用,更加易用,性能更好;
-
函數(shù)式編程:核心思想是以函數(shù)對(duì)象(可以作為入?yún)⒑头祷刂?#xff09;,無狀態(tài)(無副作用),更加強(qiáng)調(diào)程序執(zhí)行的結(jié)果而非執(zhí)行的過程,倡導(dǎo)利用若干簡單的執(zhí)行單元讓計(jì)算結(jié)果不斷漸進(jìn),逐層推導(dǎo)復(fù)雜的運(yùn)算,C++已經(jīng)提供了一些基本元素:Lambda表達(dá)式,std::function、函數(shù)對(duì)象。模板元編程等;
?
更好的類型系統(tǒng):內(nèi)置更多類型(通過標(biāo)準(zhǔn)庫擴(kuò)展),更安全類型系統(tǒng),更好類型泛化編程支持,支持自省,反射等特性;
?
更好資源的安全性:更好的對(duì)象內(nèi)存模型,更好對(duì)象所有權(quán)設(shè)計(jì)(可以學(xué)習(xí)借鑒Rust),更好異常安全機(jī)制;
?
更好利用硬件:caches,多核(更好支持并發(fā)編程),GPUs,FPGA,SIMD等;
?
?
看Bjarne Stroustrup專訪,關(guān)于程序語言設(shè)計(jì)哲學(xué)討論,更能體會(huì)到C++的核心設(shè)計(jì)思想;
?
?
關(guān)注公眾號(hào):“職場重生”? 回復(fù)“C++" 可以獲取專訪C++發(fā)明人Bjarne Stroustrup 文章的pdf。
?
C++ 的最佳實(shí)踐
?
?
我挑選一些自己覺得比較重要的實(shí)踐條目,大家可以自行修正補(bǔ)充一下:
?
-
盡量使用現(xiàn)代C++(C++11 以上)進(jìn)行C++編程,開發(fā)效率,性能,安全性都有極大提高;
?
-
盡量使用智能指針,用RAII模式管理對(duì)象生命周期;
?
-
理解C++對(duì)象的內(nèi)存模型和布局,方便定位和解決各種C++內(nèi)存問題;
?
-
異常是一個(gè)即安全又危險(xiǎn)的特性,請(qǐng)謹(jǐn)慎使用;
?
-
熟悉常見的設(shè)計(jì)模式和C++特有的設(shè)計(jì)范式,幫助自己設(shè)計(jì)構(gòu)建更好的系統(tǒng),對(duì)代碼進(jìn)行必要的重構(gòu);
?
-
代碼一定要做單元測試,測試代碼盡量覆蓋所有的分支(覆蓋率盡量高),可以采用GoogleTest單元測試框架;
?
-
代碼最好用valgrind等工具跑一遍,檢查代碼有沒有內(nèi)存泄漏和異常;
?
?
?
C++推薦書單
?
C語言:
?
《The C Programming Language》
?
學(xué)習(xí)C++,離不開C語言的了解,此書被譽(yù)為C語言的圣書,需要反復(fù)細(xì)讀。
?
手冊(cè)參考書籍:
?
《C++標(biāo)準(zhǔn)程序庫(C++ Standard Library Tutorial and Reference) 》
《C++編程規(guī)范(C++ Coding Standards) 》
?
用來當(dāng)手冊(cè)使用,有需要時(shí)候查詢一下。
?
C++初學(xué)者入門:
?
《C++ Primer》
?
此書為入門經(jīng)典書籍,初學(xué)者一定要經(jīng)常翻看。
?
如何更好編寫C++程序:
?
《Effective C++ 》:
《Effective STL》
《Exceptional C++》
?
讓你了解C++經(jīng)驗(yàn)用法,避免踩坑。
C++內(nèi)存模型:
?
?C++內(nèi)存管理全景指南
《深度搜索c++對(duì)象模型》
?
讓你理解C++內(nèi)存布局,對(duì)C++各種內(nèi)存異常問題有幫助。
?
泛型編程:
?
《深入淺出STL》
《Beyond the C++ Standard Library(Boost)》
?
可以學(xué)習(xí)泛型編程精髓。
?
modern C++:
?
《深入理解C++11》
《Effective Modern C++》
?
C++11版本以后被稱為modern C++,代表一個(gè)新時(shí)代C++誕生,寫代碼更快,更好,更穩(wěn)。
?
高手進(jìn)階
模板編程:
?
《C++ 模板完全指南(C++ Templates: The Complete Guide)》
《C++設(shè)計(jì)新思維-泛型編程與設(shè)計(jì)模式之應(yīng)用(Modern C++ Design ) 》
《C++模板元編程(C++ Template Metaprogramming)》
《Advanced c++ Programming Styles and Idioms 》
?
如果想看懂標(biāo)準(zhǔn)庫STL或者boost庫代碼,需要了解一些模板編程相關(guān)的知識(shí)。
?
設(shè)計(jì)模式:
?
《設(shè)計(jì)模式:可復(fù)用面向?qū)ο筌浖幕A(chǔ)》
《Modern C++ Design》
《More C++ Idioms》
《Advanced c++ Programming Styles and Idioms 》
?
了解一下常用設(shè)計(jì)模式和C++設(shè)計(jì)慣用方法,可以更好設(shè)計(jì)C++系統(tǒng)。
兩個(gè)經(jīng)典網(wǎng)站:
http://www.cplusplus.com
https://en.cppreference.com
用來查詢標(biāo)準(zhǔn)庫API和使用說明,以及標(biāo)準(zhǔn)說明解釋
?
往期推薦
-
C++內(nèi)存管理全景指南
-
C++模版的本質(zhì)
-
Linux調(diào)度系統(tǒng)全景指南(下篇)
-
Linux調(diào)度系統(tǒng)全景指南(終結(jié)篇)
我是Alex(艾利克斯),如果覺得文章可以,可以點(diǎn)贊,關(guān)注,在看,轉(zhuǎn)發(fā),謝謝大家支持,后面有更多精彩內(nèi)容
?
總結(jié)
以上是生活随笔為你收集整理的C++的最后一道坎|百万年薪的程序员的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux调度全景指南
- 下一篇: C++中的指针与引用