在http://some.thing.com/下有一個處理器,叫handler.xxx,那么類似下面的
URL請求,都由此處理器接收并處理。
http://some.thing.com/handler/other/string/etc
也即上面的相當于
http://some.thing.com/handler.xxx?other/string/etc
現在一個好的網絡程序,通常最多能達到多少的并發連接數?
??? ??? 在C/C++中,變量及函數的定義一般都是在.h/.hpp文件中說明原型,而在對應的.c/.cpp文件中來進行實現.
??? ??? 這種情況下,頭文件最終是給用戶使用的,以便讓用戶了解有哪些接口可以使用;而.c/.cpp文件是開發者使用的,以便讓其它開發人員了解它的實現邏輯.因此這兩個文件中肯定都是需要詳細的注釋的.在.h/.hpp文件中,主要說明函數的使用方法,如參數的意義,返回值的定義等.而.c/.cpp文件中,主要說明函數的實現邏輯等.
??? ??? 不知道上面的做法是否合適.請大家指正!
??? ??? 另外,大家在實際編程過程中是如何做的?
??? ??? 事實上,我自己在實踐過程中卻總是偏向于把注釋寫到一個地方,或者注釋原型,或者注釋實現(前者比較多),甚至干脆兩邊都寫一樣的(但這樣的話內容經常會不一樣).這樣的方法讓我在編程過程中吃盡了苦頭哇.
榮耀:一個有點兒八卦的問題。C++標準委員會中有中國人嗎?有中國人向C++標準委員會遞交過提案嗎?
Bjarne:我想不起來最近的提案和中國人有關。委員會中有一個IBM的新代表,姓王。我猜他是中國人,但我還不認識他。
考慮到中國有那么多人在從事計算機工作,我一直都很奇怪為什么看不到你們對C++0x標準化工作的參與。
我不知道這究竟是怎么回事。
自從我前段時間訂閱了Google新聞組中的comp.lang.c、c++論壇,我看到的所有帖子幾乎都是在討論C++0x標準的。給我的感覺就像這里面都是標準委員會的成員或那一類的高手,我也沒有參與過任何討論,甚至也沒細心去看看相關的問題。我也很關注C++0x標準的制定,但卻從來沒有參與進去或想過要參與進去,這又是為什么呢?
我想大多數的朋友也可能是這樣的情況吧。并不是不想參與,而是從來沒有想到過。我想這一定和我們的教育有關。我們被培養為只接受而不用去參與,我們只去被動的學習新的知識,而從沒有想過去主動的參與到新知識的產生的過程中。
不過,現在情況應該改變一下了,至少我們已經看到Bjarne先生的提醒了:我們要參與進去!不僅僅是參與C++0x的標準制定的問題,而是思想習慣的問題。
朋友們,我們要改變現在的這種思維方式了,要參與到更多的活動中去。
C++編碼規范
一、組織與策略問題
If builders built buildings the way programmers wrote programs, then the在C和C++的主要傳統中,我們認為是一種零基礎的習慣.第0條是一個根本的指示,它涵蓋了編碼規范中我們認為是最基本的建議.
first woodpecker that came along would destroy civilization.----Gerald Weinberg
在這介紹性的一節的其余部分中,我們精心選取了其中的少量問題加以闡述,這些大多與編碼本身無直接關系,但卻是寫出可靠代碼的基本工具和技術.
在這一節中我們認為最有價值的是第0條不要因小失大.(或:知道什么不需要規范化.)
0. 不要因小失大. (或:知道什么不需要規范化.)
摘要
僅說必要的話:不要堅持個人品味或陳舊的習慣.討論
真只是個人品味且不影響正確性或可讀性的結論不屬于編碼標準.任何專業程序員可以很容易地讀寫稍微不同于他所習慣的格式的代碼.在每個源文件甚至每個工程中都要用一致的格式,因為在幾種不同編碼風格的代碼片段中跳轉是很不協調的.但是不要企圖在不同項目或公司中堅持一致地格式.
下面是幾條通用的結論,這里重要的不是去制定規則,而只是要保持與你維護的文件的風格的一致:
不必明確指定要縮進多少,但要縮進以突出結構:用你喜歡的任意數量的空格縮進,但至少要在同一文件中保持一致.
不必強行保持特定的行長度,但要保持行具有可讀性:用你喜歡的任意長度的行長,但不要太長了.研究表明十個單詞以內的寬度對眼睛跟蹤是最理想的.
不要過度制定命名規則,但要用一致的命名約定:僅有兩點必須要做的:a)決不用"隱秘的"名稱,也即以一個下劃線開頭或包括雙下劃線的名稱;以及b)總是用字母全部大寫的單詞命名宏并且決不要考慮定義一個常用或縮寫單詞的宏(包括常用模板參數,比如T和U;以#define T anything定義任何東西是極其不好的做法).此外,要用一致的有意義的名稱,并按照文件或模塊的約定.(若你不能決定你自己的命名約定,試試這種方式:以各單詞首字母大寫方式命名類、函數和枚舉(LikeThis);命名變量時在前者基礎上小寫第一個單詞的首字母(likeThis);命名私有成員變量時在前者方式之后再加一個下劃線(linkThis_);以全大寫并用一個下劃線連接各單詞的方式命名宏(LINK_THIS).)
不要規定注釋的風格(除非有工具解析特定格式的注釋生成文檔),但要寫有用的注釋:如果可以的話以代碼來代替注釋(見第16條).不要在注釋中重復代碼;它們不能被同步維護.要寫解釋方法和基本原理的啟發性的注釋.
最后,不要試圖堅持陳舊的規則(見例3和例4),即使它們曾在舊編碼規范出現過.
例子
void using_k_and_r_style() {任何專業程序員都可以不費力地讀寫上面所列的任何一種風格的代碼.但要保持一致性:不要隨意的或以晦澀的嵌套方式放置括號,試著去遵循各文件中已有的風格.在本書中,我們的括號有意識的在排版的約束中以最好的可讀性的來放置.
// K&R風格
}
void putting_each_brace_on_its_own_line()
{
// 括號獨占一行
}
void or_putting_each_brace_on_its_own_line_indented()
{
// 括號獨占一行并縮進
}
參考
[BoostLRG] · [Brooks95] $12 · [Constantine95] $29 · [Keffer95] p. 1 ·
[Kernighan99] $1.1, $1.3, $1.6-7 · [Lakos96] $1.4.1, $2.7 · [McConnell93]
$9, $19 · [Stroustrup94] $4.2-3 · [Stroustrup00] $4.9.3, $6.4, $7.8, $C.1
· [Sutter00] $6, $20 · [SuttHysl01]
1. 以高警告級別干凈地編譯
摘要
將警告銘記于心:使用你的編譯器的最高警告級別.要求干凈(無警告)的構建.理解全部的警告,并通過修改代碼消除警告,而不是通過降低警告級別.討論
編譯器是你的好朋友.若它由于一個特定的結構而發出一個警告,通常你的代碼含有潛在的問題.成功構建應該是干凈的(無警告的).如若不是這樣,你將會很快養成快速瀏覽輸出結果的習慣,進而你將錯過真正的問題.(見第2條)
消除警告: a)理解它;然后b)更改你的代碼去消除警告并讓你想讓它所做的事情對人和編譯器都更清楚.
一定要做這一步,即使一開始程序看起來正確運行了,或者即使你肯定警告是良性的.即使是良性警告也可以使后面的指出真正危險的警告變得隱晦.
例子
// 文件: myproj/my_lambda.h -- 包裝Boost的lambda.hpp
// 總是使用這個文件,而不直接使用lambda.hpp.
// 注意: 我們的構建現在自動檢查: "grep lambda.hpp".
// Boost.Lambda產生我們所知道的無害的編譯警告.
// 當作者修正它時我們將移除下面的#pragma語句,但是這個頭文件仍將存在.
//
#pragma warning(push) // 僅屏蔽這個頭文件
#pragma warning(disable:4512)
#pragma warning(disable:4180)
#include#pragma warning(pop) // 恢復原來的警告級別
// … 不使用提示的用戶自定義分配器內部 …
// 警告: "unused parameter 'localityHint'"
pointer allocate( size_type numObjects, const void *localityHint = 0 ) {
return static_cast( mallocShared( numObjects * sizeof(T) ) );
}
// 新版本: 消除警告
pointer allocate( size_type numObjects, const void * /* localityHint */ = 0 ) {
return static_cast( mallocShared( numObjects * sizeof(T) ));
}
// 警告: "變量'lock'定義了但卻從未使用."
void Fun() {
Lock lock;
// …
}
// 新版本: 消除了警告
void Fun() {
Lock lock;
lock;
// …
}
// 警告: 丟失"return"
int Fun( Color c ) {
switch( c ) {
case Red: return 2;
case Green: return 0;
case Blue:
case Black: return 1;
}
}
// 新版本: 消除警告
int Fun( Color c ) {
switch( c ) {
case Red: return 2;
case Green: return 0;
case Blue:
case Black: return 1;
default: assert( !"should never get here!" ); // !"string"的值為false
return -1;
}
}
例外
有時編譯器可能發出一個厭煩的甚至欺騙性的警告(比如純粹的擾亂信息),但沒有可提供的方法去消除它,而且去修改代碼去消除它可能是不可實現的或是徒勞的工作.在這些罕見的情況下,作為一個團隊決策,除去這個只是無聊的警告的煩人的工作是:僅使特定警告無效,并盡可能是局部性的,并寫一個清晰的注釋文檔說明為什么這樣做是必要的.參考
[Meyers97] $48 · [Stroustrup94] $2.6.2
2. 使用自動構建系統
摘要
按(單個)按鈕:使用一個無需用戶參與的全自動("一鍵觸發")構建系統.討論
一個一鍵觸發式構建方法是基本的.它必須進行可靠的和可重復的轉換,將你的源文件轉換為可交付的程序包.有很多自動構建工具可以使用,沒有理由不去用它.挑選一個,使用它.我們已見過一些忽視了"一鍵觸發"式要求的組織.一些人認為隨處點幾下鼠標,就可以運行一些工具來注冊COM/CORBA服務,或通過手工定制的一個合理構建過程拷貝一些文件.但是你沒有時間和精力可以浪費在一些機器能做得更好更快的事情上.你需要一鍵觸發式的自動化的和可靠的構建.
成功的構建應該是沒有任何警告的(見第1條).理想化的構建不產生擾亂信息,而僅是一個日志消息:"構建成功完成."
有兩個構建模式:增量構建和完全構建.增量構建僅重建自上自增量構建或完全構建以來被修改過的文件.推論:兩個連續的增量構建中的后者應該沒有任何輸出文件;如果有的話,你可能有一個依賴環(見第22條),或者你的構建系統執行了不必要的操作(例如生成不合理的臨時文件而只是丟棄它們).
一個工程可以有不同形式的完全構建.考慮用一系列本質的特征確定你的構建的參數;很可能候選者就是目標式體系結構、調試和發布、或更廣(基本文件和全部文件和完全安裝).一個構建設置可以創建一個產品的基本的可執行文件和庫,另一個可能也創建一些輔助文件,一個完全充實的構建也可能創建一個包含你所有文件、可重發布的第三方庫和安裝代碼的安裝程序.
隨著工程的進行,沒有自動構建的花費也在增長.如果你一開始沒有用,你將浪費很多時間和資源.更糟糕的是,隨著自動構建成為無法抵抗的需求,你將會有比項目一開始更多的壓力.
大項目可能有一個"構建師/主管",他的工作就是照料構建系統.
參考
[Brooks95] $13, $19 · [Dewhurst03] $1 · [GnuMake] · [Stroustrup00] $9.1
3. 使用一個版本控制系統
摘要
好記性比不上爛筆頭:使用一個版本控制系統(VCS).決不要讓檢出的文件保留很長時間.一旦你的更新的單元通過測試就盡快檢入.確保檢入的代碼不會破壞整個構建.討論
幾乎所有不平凡的工程都需要一個以上的開發者和/或超過一周的工作量.在這樣的工程中,你將需要比較同一文件的歷史版本以確定變化是什么時候(和/或被誰)引入的.你也將需要控制和管理源代碼的變化.當有多個開發者時,幾個開發者很可能會在同一時間對同一文件的不同部分進行并行地更改.你需要工具以自動進行文件的檢出和恢復,以及在某些時候對并發編輯的合并.VCS自動操作和控制檢出,恢復以及合并.VCS比手工做的更快更準確.而且你不用花時間每天的去擺弄那些重復性的工作,你有軟件要寫.
不要破壞構建.在VCS中的代碼必須總是可以成功構建的.
存在很多的版本控制系統可供選擇,沒有理由不去用它.最便宜和流行的是cvs(見參考).它是一個靈活的工具,具胡TCP/IP訪問特性,可選擇性的提高安全性(通過用安全外殼SSH作為后端),卓越的腳本管理,甚至有圖形接口.許多其它VCS也將cvs作為標準去效仿,或基于它構建新的功能.
例外
從始至終只花一周左右時間的一個程序員的項目或許可以不需要VCS而生存吧.參考
[BetterSCM] · [Brooks95] $11, $13 · [CVS]
4. 在代碼審閱上作投入
摘要
代碼審閱:更多雙眼睛將會帶來更好的質量.展示你的代碼,并閱讀他人的.你們都將相互學習或受益.討論
一個良好的代碼審閱過程在許多方面都對你的團隊有好處.它可以:即使你的雇主還不支持代碼審閱方法,你也要增加管理知識(提示:要開始,給他們看這本書)以及無論如何要盡你最大努力去安排時間并引導審閱的進行.這時間是值得花的.
將代碼審閱作為你的軟件開發周期的一項常規程序.如果你和你的隊友贊同基于激勵(也可能是挫折)的獎懲制度,就會好得多.
不要做得太形式化了,寫一封簡單的郵件就足夠將代碼審閱做得很好了.這會使你更容易跟蹤自己的進程以及避免重復.
當審閱他人的代碼時,你可能想在旁邊保留一個供參考的清單.竊以為一個好的清單可能正是你正在讀的這本書的目錄表.滿意吧!
摘要:我們知道我們在給"唱詩班"布道,但是不得不說.你們的自負或自我主義也許討厭代碼審閱,但你們中的少量天才程序員喜歡它,因為它會有成效并使代碼更好,使程序更強健.
參考
[Constantine95] $10, $22, $33 · [McConnell93] $24 · [MozillaCRFAQ]
我也不知道這是怎么回事,也不是很忙啊。在自己機子上弄了幾個網頁,就在上面和同學們互相交流,寫一些文章;但現在也沒有再弄了。
我的激情好像總是很快的消逝。以后有過幾個項目的念頭,都只是剛做了個開始,花幾天或一周時間后就沒激情了。現在也是剛找了幾個同學組織了一個小的團隊來寫點程序,但經常這一個月左右后,發現我好像又想換其它的學習目標了。
我為什么總是這樣子呢?
現在心情又是周期性地落在了低谷,這一周幾乎什么都沒做。上課也都沒興趣。開了兩門選修課XML和ASP.NET;XML了解過,但不深入,老師講得太敷淺,想自己學,又不好跟老師說,擔心說我看不起老師,但學分得要啊,不選又不行;ASP.NET也是用過的,但對它沒太大興趣,看了別人的教材,那些內容基本上都知道的,通過考試是沒問題的,但還是放不下這好幾個破學分。我發現我真是給現在的教育套住了。
得下個決心了!……好像我下的決心也不少啊,但也基本上都沒能堅持幾天,唉……!
這樣的生活何時是個頭啊……
忽然發現自己這大學幾年都是在沒有任何的目標的生活著,沒有一點激情,有時候想著真是有點頹廢啊.想當初為高考拼搏時是多么的有勁啊,能在那么長的時間里一直不放松.雖然大學生活已經接近尾聲了,但還不算太晚,花點時間好好給自己確定一個目標吧!
我想大家看看我的代碼,給我一點意見和建議.