Re: [分享] The Design and Evolution of C++ 心得
看了這篇文,我也去找這本書來看。這本是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
01/15 20:33, 1F
推
01/15 20:40, , 2F
01/15 20:40, 2F
推
01/15 20:51, , 3F
01/15 20:51, 3F
→
01/15 20:52, , 4F
01/15 20:52, 4F
推
01/15 20:53, , 5F
01/15 20:53, 5F
→
01/15 20:54, , 6F
01/15 20:54, 6F
→
01/15 20:54, , 7F
01/15 20:54, 7F
推
01/15 21:01, , 8F
01/15 21:01, 8F
推
01/15 22:50, , 9F
01/15 22:50, 9F
→
01/16 12:49, , 10F
01/16 12:49, 10F
→
01/16 12:50, , 11F
01/16 12:50, 11F
→
01/16 12:51, , 12F
01/16 12:51, 12F
→
01/16 12:51, , 13F
01/16 12:51, 13F
討論串 (同標題文章)