Re: [分享] The Design and Evolution of C++ 心得

看板C_and_CPP作者 (Mark Williams)時間11年前 (2014/01/15 12:30), 編輯推噓5(508)
留言13則, 6人參與, 最新討論串2/2 (看更多)
看了這篇文,我也去找這本書來看。這本是1994年出版,20年前的舊書。 世界級的大師真的很強。 一般人對C++提出的質疑,其實他早在20年前全部都想到了。 有些真的無解,所以不改。 有些是效率太差,所以不加這功能。 有些是時間不夠,等到下一版再改。 Bjarne設計的時候,一直保持幾個大原則。 盡量與純C相容。不要求100%,但是要有99%相容。 函式庫可以作到的事情,就直接用函式庫解決。加入新特性是最後手段。 盡量不要新增關鍵字,如果真的要加,盡量用冷門的單字。 不需要為你沒用到東西付出代價。 所有功能都要考量「現實」。 包括執行效率/編譯效率/編譯器能不能實做。 實做過度困難,那就不加。 效率過差,只有高級電腦能用,那就先不加。等以後硬體進步再加。 ============================================================================== 最原始的c++編譯器,只是單純把c++代碼翻譯成純c代碼。 所以新功能還是可以用純c硬幹。只是代碼會很醜。 書裡面還寫了一段,純c模擬template的方法。(利用#define) 真華麗。 純C對於變數有三種記憶體配置方式 static stack heap 所以增加class之後,class也都支援三種方式。 而且Bjarne要求class記憶體配置要跟struct一模一樣。 先有private , public protected是比較晚加入的功能。 operator=容易造成暫存物件太多 例如這樣 string a,b,c,d; a = b+c+d; 當年就知道有這問題,只是拖到c++11才修正。 (利用新特性,右值參考) operator[]() Bjarne一開始就知道,很多人希望讀/寫需要分開處理。也曾經想過要增加新特性來分離 兩種情況。但是後來發現proxy class可解決此問題。所以最後不加新特性。 (有夠懶惰) 大家都知道garbag collection效率會比手動delete差。 所以Bjarne堅持,gc可以加入,但是不能強迫使用。 喜歡手動delete的人,可以繼續使用舊方式。 關閉gc之後,選擇手動delete。 那編出來的代碼效率,就要跟以前手動delete效率一模一樣。不可以有任何差異。 當然「選擇性」的gc是一個很困難的問題。20年後的今天還是沒加入。 set_new_handler 照理說每次new之後,都要檢查指標來確定new成功與否。 只是new使用的太頻繁,大家都很懶。所以Bjarne決定加入set_new_handler函式。 Bjarne認為平行運算還要20年才會普及。所以不願意加入平行運算功能。 (真的被他猜中了) 如果要加入,他建議使用函式庫,不須要增加新特性。 關鍵字盡量不要加太多。 例如說 int using(int namespace); 這個函式肯定編不過,因為using,namespace都是關鍵字。 所以刻意挑了using,而不是use。刻意挑了namspace,而不是scope 運氣不好的話,很多代碼要重寫。任何新關鍵字都要非常小心。 template 使用()作為括號是可以做的,編譯器沒有任何困難。 採用<>作為括號理由是,大家都覺得<>比較好閱讀。 vector<vector<int>> 兩個>>會誤判的問題,當年就知道了。 編譯器需要針對這點特殊處理。 函式加上template之後,函式回傳值也可能是未知的型別。 Bjarne希望有一種新的函式寫法,函式回傳值的聲明往後挪動。 這樣編譯器比較好寫。 到了C++11終於實現了 增加const,inline,template之後 完全不需要再用#define 而且新寫法效率一樣好。 try,catch,throw 增加三個關鍵字實在太多了。有考慮過刪除try。但發覺代碼很難閱讀。 ============================================================================== 一些沒採用的設計: contructor/destructor 原始設計是要求函式命名成new(),delete() class裡面有兩個特殊函式 call() return() 呼叫class裡面所有函式,都會先執行一次call(),再開始執行。 函式執行結束,會自動執行return()函式。 頗無聊的設計。 function overloading 原始設計要求,如果函式同名,參數不同。需要明確寫出overload關鍵字。 理由是擔心編譯器太難寫。 後來發覺自己想太多,所以也取消了。 禁止複製class 禁止在stack/heap裡面產生class 禁止class被繼承 這些都可以利用現有技術作到,不需要增加任何新特性。 Bjarne真的很懶...... 不過c++11還是新增了一點小設計,來輔助這些情況。 operator++ 最原始的版本沒有區分++在前面或是後面。 ++x; x++; 兩者都會呼叫到同個函式 有考慮過新增兩個關鍵字 prefix , postfix 也有考慮過 operator++() ++operator() 老實說我覺得++operator比較好 inherited 用來呼叫父層class的函式,就跟java的super關鍵字類似 但因為C++有多重繼承,所以inherited肯定不能用。 (C++呼叫父層class,必須明確寫出class的名字) 書裡也寫明。inherited機制可以利用typedef模擬。那就更不用加了。 include 有考慮過新增這個關鍵字,取代傳統的#include -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 118.167.22.216

01/15 20:33, , 1F
拜託...c++別再長大了
01/15 20:33, 1F

01/15 20:40, , 2F
你是看英文版的嗎?
01/15 20:40, 2F

01/15 20:51, , 3F
right reference 那個可以舉個例子嗎? 我自己想了好久
01/15 20:51, 3F

01/15 20:52, , 4F
不知道怎麼證明 right value reference 如何增加回傳效率
01/15 20:52, 4F

01/15 20:53, , 5F
因為他不是用來增加回傳效率
01/15 20:53, 5F

01/15 20:54, , 6F
它是用來讓你可以透過r-value reference去偷用r-value
01/15 20:54, 6F

01/15 20:54, , 7F
本身 避免複製
01/15 20:54, 7F

01/15 21:01, , 8F
c++長大很好啊 才會有個學不完的東西等你學
01/15 21:01, 8F

01/15 22:50, , 9F
不…我開始寫C++快五年還是覺得自己一竅不通lol
01/15 22:50, 9F

01/16 12:49, , 10F
inherited 的問題只要讓多重繼承有明確順序就可以了
01/16 12:49, 10F

01/16 12:50, , 11F
Python 也有多重繼承, 靠著 MRO 還是可以不寫父類別名稱
01/16 12:50, 11F

01/16 12:51, , 12F
我不太理解為什麼 C++ 沒有類似的東西(而且還能順便解決
01/16 12:51, 12F

01/16 12:51, , 13F
菱形繼承的問題)
01/16 12:51, 13F
文章代碼(AID): #1Irdz-GT (C_and_CPP)
文章代碼(AID): #1Irdz-GT (C_and_CPP)