assert
,可以讓問題及早被發現,也可以透過assert
與client溝通。廢話不多說,讓我先舉幾個
assert
常見的用法。參數檢查
例如有個設定月份的method,所以月份的範圍理應是1到12。所以assert
可以用來幫忙檢查傳進來的參數是否合理,如List 1。List 1 - Checks parameter
void setMonth(unsigned char month) { assert(month > 0); assert(month <= 12); if (month > 0 && month <= 12) { m_month = month; } }這裡有幾個重點要提醒,有人會想到,既然月份的範圍是1到12,那為何不寫成
assert(month > 0 && month <= 12);
一行就好?我是不建議這樣寫,原因是當assertion fail的時候debugger通常會停在該行,但像這樣混在一起寫,你就比較難分出到底是那一條件不成立,當然還是有辦法,只不過要多一些步驟,所以我建議還是分開寫,比較清楚。另外,還有人會認為既然有加
assert
了,為何還要加if (month > 0 && month <= 12)
? 這裡有個觀念很重要,通常assert
是debug版本才會有作用(當然這要看語言與環境,不過通常都是這樣),所以List 1中 line 3 與 line 4 在release版根本是空白的,如果沒有if的保護,程式還是有可能落入一個不預期的狀態。Switch Case
假設有個function在處理command,然而"目前"只有三個command定義如List 2。List 2 - Command ID
typedef enum _CommandID_ { command_attack = 0, command_heal, command_run } CommandID;如果Command ID是由我定義,而處理command的function(如List 3)是你寫的,你可以在switch case的地方加個
assert
去做個例外的警告。所以當我多加一個command ID時,而你因某種原因忘記多加一個case去處理他,這時候assert
就可以發生作用,讓我們知道這裡有一個例外發生了,不用多花時間去trace。List 3 - Switch case
void processCommand() { CommandID cmd; while (_commandQueue.count() > 0) { cmd = _commandQueue[0]; switch (cmd) { case command_attack: // attack break; case command_heal: // heal break; case command_run: // run break; default: assert(!"unknown command ID"); break; } _commandQueue.erase(_commandQueue.begin()); } }時間的關係,這篇先到此,有機會再多舉幾個例子。
沒有留言:
張貼留言