我也說說c++

任何語言都有一個由淺入深的積累過程必須靠大量的實際開發來真正理解這個語言的特性,才能真正發揮這個語言的優勢,完成各種類型的任務。

C++是一開始就把全部複雜性擺在程序員面前,必須對其基本特性有深入的理解才能寫出可用的代碼,但是一旦理解了,也就那麼回事。

java、c#、python等語言將多數複雜性封裝起來,以方便多數人的方式呈現給大家,
使的開發效率大大提高,代價是一定的開銷和在特定領域的限制。但是也保留了提高性能和完成特定任務的途徑。

一個C++的高手並不比其他語言的高手高,精通c++的人要精通其他語言同樣需要大量的學習和實踐,才能高效率的編寫優質代碼。

事實上,現在的C++真的有些誤入歧途,兼容歷史代碼的包袱固然是重要原因,但是設計者的理念纔是最根本的。

C++的語言及庫的實現存在兩個根本的衝突,爲了解決這兩個衝突導致的問題和陷阱不斷的打補丁,導致程序員需要掌握越來越多的“高級特性”。

有些人把這些高級特性當作C++強大和高深的證明,殊不知這正是C++設計缺陷的表現。

C++的第一個衝突是編程範式。c++號稱支持多種編程範式,首先是傳統的smalltalk和java式的編程,提供了在指針基礎上的繼承虛擬和多態,代表是QT;其次是以模板爲基礎的泛型和函數式編程,代表是STL和boost;

問題是,這兩種範式不完全相容,開發者需要一開始就想好要採用哪種範式(如基於iterator的算法無法用於基於虛函數接口的容器)。這還好,最麻煩的是要用的到第三方代碼的時候,需要開發者做大量的工作在不同庫之間調和。

我把前者成爲運行時多態,後者稱爲編譯時多態,編譯時多態的將多態開銷移至編譯時,調高了運行時效率,但同樣也犧牲了編譯器進行靜態類型檢查的優勢,提高了調試成本。我不認爲這是合算的。

c++的另一個衝突是面向對象編程和傳值方式的衝突。對象是一個實體,自己管理自己的內容,而傳值則需要直接處理內存佈局,爲了解決這個衝突,c++引入了各種拷貝和移動構造函數,然後爲了提高效率又引入右值引用和移動語義...

爲什麼不直接用指針呢,哦,如果用指針,就沒法直接用運算符重載,對容器算法也要做額外的工作...

當你花了不少時間構建好了自己的庫,可以得心應手的開發的時候,才發現原來自己在實現其他語言編譯器實現的功能,而且引入的開銷基本也相當於該語言和c++之間的性能差距,所以,悲劇的是,C++的性能優勢也沒了。


總的來說,在出發點和目的地之間,C++提供了一個龐大的網絡,裏面有最近的路徑,也有非常遠的路徑,需要程序員自己去發現,這需要數年的實踐才能做到。而java、c#等語言之提供了一條或爲數不多的對多數人滿意的路徑,程序員不用選擇,照着走就行了,這隻要數月的訓練就能達到。


所以我對初學者的建議是,如果自己可以選擇,在可能的情況下(考慮任務、第三方庫)使用java、c#等更高級的語言,性能的差距沒你想的那麼大,但是開發效率可以提高十倍。

反過來,如果我要招聘c++程序員,我寧願花3倍的價錢找有多年實際開發經驗的,也不要免費的初學者。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章