對話#28:Contracts, Promises, and Mere Semantics (轉)

worldblog發表於2007-12-12
對話#28:Contracts, Promises, and Mere Semantics (轉)[@more@]


和大多數日子一樣,我開始了那天的工作-在我的方形房間內,端著新鮮的咖啡,在開始寫程式碼前,正收著早上的e。很奇特,它這天,Guru沒有突然出現在我身後。實際上,我無意中聽到它發生在另外一個人身上。 :namespace prefix = o ns = "urn:schemas--com::office" />

我正坐在書桌前安靜地工作著,而且聽到附近的同事們擊鍵的時間,這是傳來。

“時間到了,”Guru說,“談些事吧。”

我習慣性地跳了起來。我四處尋視了一下,但Guru並沒站在我身後。我接著聽到隔壁房間傳來椅子的吱吱聲-是Kerry,我們組聰明而又令人討厭的新人,從他椅子上跳起來。她正和他在一起。我懷疑他能持續多久;Guru以最開頭幾個月內嚇跑絕大多數的新人而著稱,根本等不到轉正。Kerry已經表現為早期的崩潰症狀。我估計他將只能再堅持幾個星期了。

我懷著稍微的內疚偷聽著:

“鮑伯告訴我,我的新程式碼中有一個問題……”我聽到Kerry開始反抗。

“是嗎,我的孩子?”我能回想出她的眉毛翹起來,向我笑著的樣子。

“嗯……是的。是關於編碼規範的事,我將自己搞定它……”

我聽到了書合上的聲音。Guru肯定已經合上了她帶的“磚頭”。我懶得猜她今天帶的是哪本。“告訴我,年輕的,”我聽到Guru對Kerry說,“我們的編碼規範說什麼了?說吧。”

“嗯……他們就在這裡。”在Kerry擊鍵的同時,我也悄聲地調出同一並找到他正背誦的位置。這是其中的一部分:

當申明引數型別時,最好遵循傳統的C++介面慣用法:

如果實參需要被更改,傳指標。

如果實參不被更改,傳值。

“我沒這麼做,所以鮑伯指出它。就是這麼多。這是對的。這是對的;我將修改;真的,”Kerry說完了,聽起來很緊張。

有一個停頓,我在猜測Guru是在微笑或皺眉。最後,她說:“照他的話做……就現在。程式碼,但別chek in。而是把更新過的程式碼給鮑伯,讓他檢視,並讓他自己使用,然後等待。”

“等候?……為什麼?”Kerry問。

這次我確定Guru在微笑。“只需等待,徒弟,”她說道,然後我聽到了紙的沙沙聲和後退的腳步聲。

表演結束,我想,於是回去工作。但是最精彩的部分總要上演的……


幾個小時之後,我正狂寫程式碼時,聽到Kerry被叫到鮑伯的辦公書桌,雖然稍微有些遠,但還沒遠到讓我聽不見鮑伯狂訓Kerry的聲音。

又過了一會兒,鮑伯似乎訓夠了,Kerry被放了回來,孤獨地 (我想)回到他的房間。當他坐下時,椅子吱吱地響了一下,然後又變得寂靜……但沒維持多久。

大約五分鐘之後,又次傳來Guru的聲音,Kerry的椅子又吱吱響了一下(或是Kerry發的?他已經習慣在Guru出現時發出吱吱聲),又一次的對話:

“關於C語言為什麼是燙手的,”Guru突然說道,“而豬是否有翅膀。”我在笑後面一句話,知道她可能在說鮑伯。

(吱吱聲)“我……我跟鮑伯說了……”

“的確,你這麼做了,孩子,越過整個建築我都能聽到,”傳來Guru柔和的聲音。又傳來一聲書本很快合上的聲音。“而他說了什麼?”

“我的程式碼一定是錯的;它讓他程式碼不能工作了,”Kerry結結巴巴的。“但是我不知道我做錯了什麼。我就是按他所說的做的!我也就是按編碼規範說的做的!”

“啊,”-我眼前浮現出Guru銳利地微笑-“但它們是同一回事。因為鮑伯是制訂這部分編碼規範的人之一。”

“……他……他是?”

“哦,是的。他確實是,徒弟。這也就是編碼規範發生錯誤的原因。”

“錯誤?”

“那對C++慣用法而言是錯誤的,”她繼續說道。

“雖然,它對於沒有'引用'的C語言是正確的。”

“但是……如果是錯的,他們為什麼不更新?”

“我們的新經理,Pete Williams,過於信任鮑伯而看不清實際需要,”她嘆息道。“他的前任也沒有這麼做。於是,編碼規範並不正確。C++慣用法更象這個……”我聽到了書寫筆在白板上的吱吱聲,這是我後來在白板上看到的:

當申明引數型別時,最好遵循傳統的C++介面慣用法,除非它不合適:

如果實參需要被改變,傳非const的指標或引用。

如果實參不被改變,傳const的引用,或在複製開銷很小時傳值。

“這樣的陳述比較接近事實,”Guru總結了一下,“但是,徒弟,你必須注意'最好'和'除非'這兩個詞。這只是慣用法。不是教條。它不是沒有例外的。”

“嗯……是的。沒問題。鮑伯說,它適用於他試過的每件事物,除了……”

“auto_ptr,”Guru點點頭,替他說了出來,我聽到她繼續在白板上寫著。

Kerry發出了驚訝的聲音。“你怎麼知道的!鮑伯告訴你的?你看見的?”

“我就是知道。我不需要看見。”她繼續在白板上的寫著,而這裡是我幾分鐘之後看見的:

template

void Mutate( T* byPointer );

template

void Mutate( T& byReference );

template

void LeaveAlone( const T* byPointerToConst );

template

void LeaveAlone( const T& byReferenceToConst );

template

void LeaveAlone( T byValue );

“想一下這個例子,然後回答:對於哪種型別的T,的名字是名副其實的?徒弟!”她說道。

我不知道她說的是我,直到我聽到一種不同的啪嗒聲,一塊橡皮從我頭上反彈開去。然後我很快反應過來,揉了揉頭,加入他們。

 “嗯?什麼?” 我嘟囔了一句。“我正忙著工作。” “實際上你正專心於豎著耳朵。”Guru眯起眼睛一會兒,假裝煩惱, 然後我看見她閃爍的目光。放下書寫筆後,她又開啟她的厚書,將頭髮掛於耳後,微笑著走開了。“我的徒弟將會解釋的,我的孩子……” 她的分別語從肩頭飄來,就在她轉彎消失的那瞬間。

我搖頭咧嘴而笑。什麼行為!但Kerry古怪地看著我,我懷疑也許他還沒開始把我和Guru同歸在“神奇人士”之列。我發現我不會介意的,如果他這麼做了的話;這給了我一個有趣的啟示。

“年輕人,”我微笑著說道,一認識到我剛說了什麼,就笑得更歡了,“當你傳遞一個auto_ptr是,會發生什麼?”

“嗯……噢!”很清楚,Kerry已經明白了。“傳遞了所有權!她說的是這個意思嗎?”

“是的,”我同意。“你已經明白了。而同樣事還發生在所有會轉移所有權類-順便提一句,其典型特徵是在複製建構函式的形參上使用非const的引用。這就是你要的答案:傳值通常意味著你不會碰源物件,除了auto_ptr,對它含義正相反-並且更差,因為不但修改了源 auto_ptr,還將它置為了NULL。而傳指標常意味著準備修改源物件,除了auto_ptr,對它含義正相反-你正在避免修改它。對於auto_ptr,傳統的慣用法正幹著壞事。而這正是基於通常的慣用法的程式碼,例如容器對它們所包容的物件作的假設,不能和auto_ptr協同工作的原因。但不只是對於auto_ptr;對所有在複製時進行所有權傳遞的類都是這樣。總要特別留心在複製建構函式中的非const引用引數;那就是你通常會遺漏的致命之處。”

“現在,”我一邊走一邊讓我的聲音飄向身後,“我必須回去繼續我的沉思了。”我到達走道末端,轉了個彎,剛從他視野中消失,就再也忍不住得發出了吃吃地笑聲。

[參考文獻]

[1] H. Sutter and J. Hyslop. “Conversations: A Midsummer Night's Madness,” C/C++ Users Journal C++ Experts Forum, August 2002.

 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-991803/,如需轉載,請註明出處,否則將追究法律責任。

相關文章