目前吵的很兇。
都說什么C++快不行了,可是游戲開發(fā)這種東西,還是非C++莫屬,圖形開發(fā)這塊C++還是強項。我發(fā)現(xiàn)C#,JAVA之類的之所以能在企業(yè)級應(yīng)用和快速開發(fā)方面占有優(yōu)勢,完全是因為別人已經(jīng)幫你封裝好了一套好用的API函數(shù),而不是這些語言的語法機制本身提供了多少優(yōu)點,而C++和C卻不這么做,因為C/C++相信使用它的程序員完全有能力自己封裝,沒必要替他們封裝。
對于C++提供的繼承、模板等高級特性,應(yīng)該謹(jǐn)慎使用,盡量做到繼承的層次很少,各個類之間是組合關(guān)系,從而達成一種平板結(jié)構(gòu),以實現(xiàn)各個類之間最低的耦合度,降低維護和理解的成本。同時由于類隱藏了數(shù)據(jù),又將特定的數(shù)據(jù)和函數(shù)綁定在了一起,這樣就可以減少全局變量的使用,降低了由于大量使用全局變量所引發(fā)的風(fēng)險。同時類的封裝降低了各個函數(shù)之間通信的成本,減少了函數(shù)參數(shù)的個數(shù),而通過多態(tài)這一特性可以更加有效地降低函數(shù)調(diào)用的參數(shù)個數(shù)。
C與C++通過良好的設(shè)計都可以架構(gòu)一個優(yōu)秀的框架,而C++通過面向?qū)ο筮@一特性(類、繼承、多態(tài)等)可以更加有效的實現(xiàn)封裝和信息隱藏,但架構(gòu)不應(yīng)該太復(fù)雜,繼承層次不要過多,類和類應(yīng)該盡量是一種平板組合關(guān)系。
我的觀點是少一點語言之爭,多學(xué)一點實用的技術(shù),真正起決定作用的往往是對具體技術(shù)的掌握,比如Windows運行機制,Windows網(wǎng)絡(luò)編程基礎(chǔ),API函數(shù),3D數(shù)學(xué)基礎(chǔ),3D圖形學(xué)基礎(chǔ),DirectX提供的具體接口和函數(shù),游戲制作技術(shù)的熟悉,以及數(shù)據(jù)結(jié)構(gòu)和算法等等,到最后用什么語言來實現(xiàn)其實是一個次要的問題了。至于架構(gòu)好點差點倒不是最重要的,沒有這些基礎(chǔ)知識的積累,東西憋都憋不出來,更不要談什么架構(gòu)了。
附一些網(wǎng)友的觀點:
我對 C 和 C++都很喜歡,但是更喜歡用 C,因為比較簡單。C++也很好,只是許多特性都用不上,我喜歡用最簡單的辦法去解決實際的問題,并盡量保證其合理性。做設(shè)計應(yīng)當(dāng)以實際問題為出發(fā)點,作抽象是好的,但是任何事物都有適用范圍,沒有人能夠?qū)懗鐾耆ㄓ玫摹⑵者m的代碼,用 C++ 也做不到。這類似于以不變應(yīng)萬變和隨機應(yīng)變之間的關(guān)系。C++程序員有時候太過執(zhí)著于抽象設(shè)計,執(zhí)著于通用庫的設(shè)計,執(zhí)著于可重用,執(zhí)著于面向?qū)ο螅灾劣谕嗽O(shè)計的根本是為了解決實際問題,忘了除了面向?qū)ο蟮脑O(shè)計方法還有更多其他的設(shè)計方法,忘了設(shè)計的簡潔,忘了設(shè)計是否容易被他人所理解,忘了除了重用,還有更多需要注意的地方。C++使人們在設(shè)計時,在面向?qū)ο蟆⒊橄蠛涂芍赜蒙媳成狭颂喟ぃ灾劣谠S多人沉溺其中,而沒有更多的精力去做更多的事情。
以不變應(yīng)萬變是相對的,而隨機應(yīng)變則是絕對的。也就類似于靜止是相對的,而運動與變化是絕對的,這樣一個哲學(xué)道理。因此,從這個角度上將,修改或重寫代碼都是絕對會發(fā)生的。而我們盡力所要保證的重用性,其實都是相對的重用性。因此,有必要考慮,是否真的需要花費大量的精力,去保證這種相對的可重性。
我之所以要這樣講,是因為近幾年,可重用性被強調(diào)得太多太過。以至于人們忘了自己真的需要做什么。
相對于代碼的可重用性,我更加看重代碼的可維護性和可擴展性。好的代碼都是開放的,可維護,可擴展的。盡量保持扁平的層次結(jié)構(gòu),盡量使用基本的數(shù)據(jù)類型,盡量減少自定義的數(shù)據(jù)類型,使整個系統(tǒng)的設(shè)計更加容易被人所理解。
真正好的設(shè)計,都是開放的,簡潔的,易于理解的。畢竟維護的最基本的條件,就是先要理解現(xiàn)有的代碼。
而所謂的可重用性和抽象,都給以上目標(biāo)的實現(xiàn),帶來了極大的障礙。因此需要根據(jù)實際需求,在各個方面取得平衡。否則,一切關(guān)于語言的爭論都是毫無意義的。
一個系統(tǒng),不管你設(shè)計得多么抽象,多么可重用,他總有適用的范圍。而為了達到重用和抽象,所使用的技巧不管多么高明,如果它很難被理解的話也是毫無意義的。因為這個系統(tǒng)總有一天會走出他的適用范圍,這個時候就需要修改和維護其代碼。如果這個系統(tǒng)很難維護,那么,就算它當(dāng)初的設(shè)計很高明,但也走到了生命的盡頭,逃脫不了被重寫的命運。
因此,從實際出發(fā),分清主次,做自己真正該做的事情才是關(guān)鍵。感覺可重用和面向?qū)ο蟊粡娬{(diào)得太過,以至于人們迷失了方向。
學(xué)習(xí)期。 c,簡單,干練。簡單到?jīng)]什么好學(xué)的。有用的技能都是在實際運用中獲得exp然后lvup的。可以這么說,初學(xué)者可以很快得掌握c,但是基本上卻什么都不能做。立竿不能見影。這是c的簡單干練所決定的,是必然的。 c++,復(fù)雜,強大。c++的這些特點已經(jīng)無須論證。遍地開花的垃圾c++程序員用鐵一般的事實說明了一切。針對于與c的比較,仍然來說說立竿見影的問題。我的觀點是,雖然這一點c++做得比c好一些,但是仍然不能達到立竿見影的程度。結(jié)論,就這個階段來說,不分勝負(fù)。
開發(fā)期。在任何軟工項目都處于“硬件受限”的時代和環(huán)境下,c是毫無疑問的王者。(當(dāng)然,如果你腦容量可堪負(fù)荷,請使用asm)但是在現(xiàn)在,情況分2種。第1種,我是一個獨裁者。當(dāng)我需要清楚地知道我的代碼做了什么的時候,c->asm仍然是最適合的合作者。這種人多半是戰(zhàn)斗在“硬件受限”的原始時代。Linus就處于這樣一種時代,所以他不得不用c。不要告訴我linux可以跑在多么牛B的機器上,內(nèi)存可以多么的大,這是p話,linux的 kernel必須不能用盡一切可以觸及的資源,因為它只是一個承載其他東西的方舟,他必須委屈自己假裝是在一個超級受限的環(huán)境下工作,把美味的梨子讓出來給依賴著它的兄弟姐妹們。所以,kernel類的開發(fā)者毫無疑問是戰(zhàn)斗在一個“硬件受限”的原始時代,c->asm是他們最好的合作者。 ps.游戲引擎也算半個“硬件受限”環(huán)境。雖然不需要承載如kernel般繁多的東西,但是引擎最終將被用來產(chǎn)生實作品,從設(shè)計者的角度出發(fā),也必須在一定規(guī)模——沒錯,就是規(guī)模——上考慮到由這個引擎所生產(chǎn)出來的東西將要產(chǎn)生的負(fù)荷——這毫無疑問地成為了一個“受限”的環(huán)境。——但是盡管如此,c- >asm也不一定就是最優(yōu)解,在我的觀點來看,這是語言無關(guān)的——當(dāng)然,目前可以做出的選擇不多,就個人而言,我仍然選擇了c++。第2種,我是一個追求高產(chǎn)的商人。在性能要求不太嚴(yán)苛的情況下,c就是一個渣。太多的東西需要自己去做,這意味著將會帶來冗長的開發(fā)周期,這會導(dǎo)致成本的急劇增長,包括各種可量化的(人力物力財力)和不可量化的(團隊穩(wěn)固性團隊士氣)成本。因此,在這種環(huán)境下,c就是一個渣。c++毫無疑問比c做得好。但是,在這個領(lǐng)域里,c和目前的c++都已經(jīng)失去了輝煌的寶座,新生代的高級語言都擁有給他們致命一擊的實力。結(jié)論,從表面來看,仍然是不分勝負(fù)。但是c在這一階段具有穩(wěn)定、明確的應(yīng)用領(lǐng)域,算是小勝吧。
運行期。仍然是分成2種情況,效率關(guān)鍵和效率不關(guān)鍵的。在避開其他環(huán)節(jié)的情況下,前者當(dāng)然比后者更受歡迎。但是,運行期的效率直接與開發(fā)期的質(zhì)量相關(guān),因此運行期的事又是不可能和開發(fā)期完全隔開的。 “不管用什么樣的語言,都可以寫出糟糕的程序。”——這話也可以反過來說,“用任何一種語言,都可以寫出優(yōu)秀的程序。” 因此,在我眼中,這仍然是一個語言無關(guān)的問題。不要把失敗的理由放在你無法控制的地方,優(yōu)秀的進化者會改變自己適應(yīng)環(huán)境。——這是我的觀點,因此,我更希望自己能成為“用任何一種語言,都可以寫出優(yōu)秀的程序”這樣一個開發(fā)者。我認(rèn)為,每一個以成為優(yōu)秀開發(fā)者為目標(biāo)的程序員,都應(yīng)該以這樣一種精神為指導(dǎo),雖然不一定要確實地做到,但是應(yīng)該具備這樣一種精神。用更容易理解的話來說,就是要做到手中有劍心中無劍(請注意這跟武俠小說上的說法是反的-_-!)結(jié)論,既然都語言無關(guān)了,當(dāng)然沒有勝負(fù)之說。
維護期。 OK,這實際上是一個軟工項目中生命周期最長的階段。這里涉及了很多東西,最主要的就是3個方面:調(diào)試、維護、復(fù)用。這三個議題每一項都可以大書特書再書還要書。既然是生命期中最長的一個階段,因此c對c++的重量級攻擊放在這里當(dāng)然就會很有效果。在維護上的代價而言,結(jié)構(gòu)過程化的c比抽象對象化的c++便宜太多了。這是“結(jié)構(gòu)過程化”與“抽象對象化”的根本不同所造成的差別。用程序員們更能夠理解的方式來說,c就像一個鏈表,要增減head很方便;而c++就像一個動態(tài)數(shù)組,要insert[0]或者remove[0]就要牽一發(fā)而動全身!但是,c真的就很好維護么?非也!一個瘋狂使用#define的c程序,不會比一個濫用oo特性的c++程序更好調(diào)試和維護。因此,這仍然是與開發(fā)期工作的質(zhì)量息息相關(guān)的。結(jié)論,好吧,我不得不說,在我眼中c和c++仍然不分勝負(fù)。
綜上所述,c和c++在我眼中不分好壞,具有同等的地位。他們分別代表了兩種不同的編程思想。 “結(jié)構(gòu)過程化”的c帶來的好處是賦予程序員更為強大的控制力,和維護期可以“斷章取義”的靈活性——但是代價是更多你不得不親歷親為的工作。 “抽象對象化”的c++帶來的好處是更為貼近現(xiàn)實的思維要求,以及更具親和力的“人機交互接口”——當(dāng)然,代價是需要你練好足夠的基本功來了解c++在背后到底做了些什么,以及在維護期和復(fù)用階段你可能要面臨的“抽筋”式的痛苦。
作為一個擁有美好愿望的程序員,我希望有一種語言,既能給我c的強大控制力和維護期的靈活性,又能給我c++的親和力和強大的——好吧,我承認(rèn)我比較喜歡template那種拐彎抹角的東西——腦力訓(xùn)練(—_,—),然后,又能輕易地滿足KISS的原則——這將可以讓我非常簡單地找到高質(zhì)量的合作者 ——畢竟怪物級的c/c++程序員不是像現(xiàn)在的本科生一樣遍地都是。而且基于c/c++的靈活性——這里叫做不確定性更好——這一特征,每個怪物級的 c/c++程序員都有很大可能不能跟另一個怪物互相咬合他們腦袋里高速轉(zhuǎn)動的齒輪——如果你非要那么做,這很可能會帶給你更多的機會讓你的項目走火入魔,甚至停擺,最后以自爆收場。
但是遺憾的是,目前這只能是一個美好的愿望而已,我不得不采取折中的辦法來找一些代替品。因此,目前我的做法是,用c的規(guī)則來寫c++的程序,略微地用一些可以被我完全控制的c++的特性(模板的編譯期編程技術(shù)很贊,可以為運行期的效率和正確性帶來很大的好處),最根本的出發(fā)點是建立在獲得強大控制力和可預(yù)期的維護期工作量的目的之上的,當(dāng)然,還有不能忽視的效率問題——我的目標(biāo)是一個可擴展的游戲引擎。
胡言亂語了一堆也不知道說了些啥……最后做個總結(jié)性發(fā)言吧:c和c++都不是什么好東西,但是正如windows也不是什么好東西一樣,我們卻非得要用它們——至少在可以預(yù)見的一段不會算短的時期內(nèi)。
另外,撇開c/c++的比較說點跑題的話。
c++目前確實處于一個相當(dāng)尷尬的境地,高不成低不就,過于復(fù)雜龐大的身軀又成為了他能夠被更熟練掌握的門檻。c++目前有兩條路可走,一是朝c退過去,二是朝更高之處攀登。但是無論走哪一邊,都是“強敵環(huán)視”,要想闖出一片新的天空,恐怕需要劍走偏鋒了。至于是不是一定要偏著走,偏又要怎么個偏法,我也說不出個所以然來,且讓我們拭目以待吧。而c,很可能將會止步于“硬件受限”的時代吧,然后在這個時代和環(huán)境下再一點一點地進化,最終與c++將來的終點完全分道揚鑣。
個人以為,程序語言的發(fā)展以后將會明確地分出兩個方向,一個是以c為代表的“底層親和”的語言,它們的特點是將給于程序員最大的控制能力,讓一切盡在程序員的掌握之中。另一個將是以不斷發(fā)展的新興高級語言為代表的方向,也可能是c++以后的方向,它們的特點是不斷地將底層的東西從程序員的眼前隱藏起來,讓程序員的門檻降得更低,充分地體現(xiàn)出KISS原則,并從而提高生產(chǎn)力和生產(chǎn)效率。
人類的知識累積將隨著時間的流逝慢慢增長,如果沒有一種有效的途徑讓后來者可以從更高的地方起步的話,光是學(xué)習(xí)就足以耗盡人的一生了。因此我認(rèn)為,“隱藏底層的東西”,將成為今后應(yīng)用軟件技術(shù)發(fā)展的關(guān)鍵,說白了就是讓程序員傻瓜化。
本是同根生, 相煎何太急. C/C++本來就是用來開發(fā)系統(tǒng)級應(yīng)用的, 有何必強分彼此呢?
在程序開發(fā)中, 最重要的根本就不是語言,而是設(shè)計(在這點上面, Linus說得是對的).
之后的問題: 效率, 重用, 擴展等等問題都取決于你的設(shè)計和軟件的要求. 這個并不存在絕對的標(biāo)準(zhǔn). 說C++開發(fā)不好的兄弟們, 請考慮考慮, 如果你用C改寫同樣的軟件, 你可以保證寫出來的軟件質(zhì)量就一定好過用C++寫的?
c/C++當(dāng)然存在個自適用范圍的情況, 一般認(rèn)為C比較適合OS內(nèi)核和遷入式的開發(fā). 而C++一般不太適合在這兩種環(huán)境下面. 這個原因是很多的, 其中很重要的一個原因是由于C++的OO特性會產(chǎn)生不必要的負(fù)載(其實, 如果軟件設(shè)計得當(dāng)?shù)脑?加上一個合適的編譯器, 這個并不是很大的問題. 在這裡,就假定C++不適合這些領(lǐng)域). 但是做游戲領(lǐng)域呢? 圖形介面領(lǐng)域呢? C++就非常合適(而C在這裡就顯得麻煩了). 兩種語言都有長處和不足.
C++由于提供了太多的內(nèi)容(OO/模板/泛型...), 導(dǎo)致了大家有太多的選擇, 結(jié)果在軟件設(shè)計的地方錯用了C++的特性, 導(dǎo)致了軟件的各種問題(效率差, 不可擴展等等). 這個是設(shè)計的問題, 而不是語言錯誤. 不要把自己的設(shè)計缺陷推到C++上面, 然后反過來指責(zé)C++. 老實說, 這樣的設(shè)計水平, 用任何語言都做不出來好的軟件.
至于Linus說的C++是垃圾之類的話, 不用去當(dāng)真. 他開發(fā)出了Linux, 是很好. 但不表示他說的話就是真理. 我相信那只是爭論時候的激憤之言(而且有特定的環(huán)境, 某位老兄批評了一把他寫的git軟件, 有點小器). Linus是人, 不是神. 用不著頂禮膜拜.
軟件質(zhì)量取決于設(shè)計而不是開發(fā)語言.