C與C++的個人反思

這個話題歷來有很大爭議, 喜歡C的對C++不屑一顧,喜歡C++的覺得C是一個子集合。


最早接觸C語言是高中時候, 那時一幫搞奧數的同學,有人帶了一本譚浩強的書,於是大家學得熱火朝天。師大附中的3年,是人生最自卑的3年。一個宿舍8個人, 湖南省前6名就有4個被宿舍牛人佔了。這3年最大的打擊就是自己智商怎麼怎麼低。有人說搞IT的都智商比較高, 那看和誰比了, 和搞數學的比,就基本全是弱智了。記得那時看了一個月,也沒明白賦值是怎麼回事。宿舍一哥們, 看了一個星期就搞懂了。一打聽, 媽的, 人家中考700分考695的。心理壓力那個大啊。


然後就是3年後,99年到了上海, 第一門課就是C++語言。 那時是面向對象的頂峯。我也免不了。憑着自己的小聰明, 一個暑假看完同濟大學的高等數學, 然後第一學期的高數免修時間就全部用來學C++。這一入火坑就是6年。回顧這6年, 我現在後悔了。 脫離實際, 被語言細節玩死了。 看了一大堆書, 懂一大堆理論,實際項目到底如何面向對象分析還是一頭霧水。 歷史如果能夠重來, 我情願學習另一門語言, 英語。回過頭來看, 我花了大量時間,看了大量書, 但脫離實際, 基本上是在岸上游。再加上C++語法過於繁雜。

客觀上也讓學習者找不到北。


其實上, C++最大的問題就是死在搞不懂它的設計哲學。坦率的地說,我學習了6年,工作中又用了4年, 我還是沒自信說我懂C++。更主要的是, 我沒有搞懂多繼承到底怎麼用。面向對象裏,我最搞不懂的就是繼承。繼承的最大問題就是破壞封裝。這2者的平衡實在是太難掌握了。現在各種面向對象實現版本,繼承是最大問題。

首先現實中的繼承都是部分繼承。 比如,繼承父母的財產。你只能繼承一部分,不可能繼承所有。然後, 是繼承父母的性格。但,你會和父母的性格完全一致嗎, 顯然不可能。

這中間的差別就在於, 雖然能繼承A,和B, 但你沒有辦法讓系統自動解決A和B之間的融合, 構建一個新的C。即C很難只繼承A類的X函數的部分特性,再繼承B類的Y函數的部分特性。如果你直接調用A.X 和B.Y,顯然由於A和B是高耦合, 這必然會帶來一些副作用。如果要修改這些副作用, 你必然又要影響A和B的封裝。矛盾就在於, 作爲子類, 你

沒有權力修改A和B。 問題的關鍵就是,現實的繼承都有融合和進化。 而目前的面嚮對象語言基本上很難提供有價值的工具來解決融合和進化。


這樣,我們很快就會發現, 系統並沒有變得更簡單, 反而更復雜了。我們本意是想通過工具來簡化系統,卻事與願違,讓自己更暈了。

而C爲什麼沒有這個包袱呢? 因爲C完全是你自己控制整個融合。只有人才能精確的知道A類哪些屬性是自己想要的, 哪些是垃圾數據。只有人才能清楚的知道哪些函數滿足isA關係,哪些函數必須丟棄,哪些函數還可以改改用用。

這中間的最大差別是, 你將問題丟給C++, 但事實上它並沒有你想的那麼強大。而C是完全告訴你,對不起,這個搞不定,必須你自己來。


這樣,最終結果就是, 系統雖然對外接口看起來很完美, 裏面相互衝突相互矛盾的東西一大堆。你原以爲能在下一個系統中完美重用, 卻發現一旦抽象的映射關係由於項目的變化,而導致大量的isA關係變成isNotA關係。怎麼辦? 將上千個類完全重寫? 事實上,光自上而下檢查所有isA關係就已經讓你吐血了。更不用說再在高內聚的類上動刀子解耦。工作這麼多年,C++讓我最開心的就是,這個庫你們負責,我只管調接口。 這的確比C稍微快一點,少敲了一些 void*this, 但如果讓我去改某個號稱C++高手,其實只是胡亂寫了2-3年代碼的人, 我只能往上追溯XXX年,(略500字)


當然,上面這個問題不是C++的問題,是所有面嚮對象語言通用的問題。這些號稱無敵的工具, 卻完全沒有智能, 一旦抽象關係發生變化,它們什麼也幹不了。而一旦人來維護這些關係的時候, 卻發現還不如重寫, C+V操作來得快。


我喜歡C的最大原因就是它的哲學: 能幹的一定幫你幹好, 不能幹的你自己必須幹好。  決定一切的不是計算機,而是人。


關於效率問題, C一直被人詬病, 其實你完全可以C + 自己構建的語言來解決。 我去年就自己設計了一個簡單的語言, 能快速地將描述性代碼轉換爲面向對象版C語言。

誰說C不能面向對象? 說C不能面向對象的人, 其實是自己還沒懂面向對象。 看起來好像學了C++, 懂了,其實完全只是爲了方便C+V, 卻完全不管父類裏面10個函數有8個不滿足isA關係。 沒事,只要我這個項目只用10箇中的2個就可以。後面項目有沒有,還在不在這個公司誰知道呢?

發佈了122 篇原創文章 · 獲贊 34 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章