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