2010-12-13 87 views
1

在另一個線程的評論中告訴我,只要發生任何不尋常的事情,我都應該使用異常,即使它不是致命的腳本。這想出了爲我所用結構類似於如下:C++非致命異常處理

return err("File could not be loaded"); 

這將打印錯誤到屏幕上,並返回false,終止指令處理。有人建議,除非有例外情況,否則這樣做會更好。

問題在於,對於所有意圖和目的,程序都是通過控制檯控制的語言解釋程序,這意味着只要命令輸入錯誤或者解釋代碼中存在錯誤,就會出現錯誤需要顯示。

除了這些問題似乎很少被作爲例外處理的事實之外,應該如何實施呢?如何使用try塊來控制處理路徑?例如,目前我的代碼如下:

if(!validate(code)) 
    return false; //the validate function already having output the error 
else 
    process(code); 

我應該如何保證過程(代碼)只執行,如果驗證(代碼)獲得成功嗎?我應該只是從catch塊中的函數return false;?這似乎回到了使用返回值處理異常事件的原始問題。這在我看來,最根本的問題是,這些問題是不是在所有的異常,但我聽從那些有更多的經驗比我

+0

毫無疑問,你會得到很多回答:「例外只適用於特殊情況。」請忽略它們。 – 2010-12-13 21:21:20

+0

@John Dibling:例外或評論? – 2010-12-13 21:27:00

+0

是的,如果你不理睬,你也可以忽略,「使用明確有意義的名稱」,「RAII是你的朋友」,「不要添加不必要的耦合」,以及任何其他各種人們說你應該遵循的事情來編寫清晰且易於維護的代碼。 – 2010-12-13 21:30:01

回答

2
try 
{ 
    validate(code); 
    process(code); 
} 
catch(...) 
{ 
    return false; 
} 
return true; 

假設validate拋出,process不會發生。

1

的問題是,你有你的功能設置爲使用返回代碼。當你的代碼已經設置了返回值時,你不能只拖放異常。

做正確的做法是像

std::string code; 
// input into code 
try { 
    validate(code); 
    process(code); // Throws an exception. 
} 
catch(std::runtime_error& except) { 
    std::cout << except.what(); 
    // recover from here. 
} 
+0

1)這只是在一小組假設情況下的正確方法。 2)使用cerr進行錯誤報告! – 2010-12-13 21:32:14

3

例外的想法是,你不會需要像一個單獨的「驗證」步驟。每當「進程」到達某個地方發生故障的地方時,拋出一個異常。

如果您確實需要某種原因一個單獨的驗證步驟,然後它會看起來像

validate(code); 
process(code); 

驗證會拋出失敗異常,在這種情況下過程將永遠不會達到。

+0

但是,這是不是假設代碼將在發生異常時完全終止?如果不是,代碼將如何返回到主控制檯循環?編輯:我明白你在說什麼。沒有抓住暗示的嘗試塊。 – wyatt 2010-12-13 21:28:14

+1

'while(!quit){try {process_command_line(); } catch(const std :: exception&ex){cout <<「Error:」<< ex.what()<< endl; }}' – 2010-12-13 21:31:36

+0

+1的第一段。驗證代碼很容易用返回代碼來設置,而處理代碼可能很容易在幾層以內,返回代碼很尷尬。 – 2010-12-13 21:32:35

4

如果操作可 - 設計 - 在布爾值,無論是成功或失敗,而這兩個都是常見的,這可能是最清楚的結構的錯誤檢查「明確」這樣的方式您的命令流,像「驗證」功能。

如果您不想打擾您的常規控制流程,並且錯誤檢查並希望將檢查移動到其他地方,也許是上面的某些函數調用級別,那麼異常派上用場。

你的情況聽起來好像你並不真正需要的例外。如果你的代碼看起來乾淨,沒有他們,和它呆在一起。

2

也許你想你的頂級環路是這個樣子:

while (!quit) { 
    try { 
     process_command_line_input(); 
    } 
    catch (const std::exception& ex) { 
     std::cerr << "Error: " << ex.what() << std::endl; 
    } 
} 

所以,process_command_line_input()獲取輸入的下一行,爲所欲爲它。如果檢測到任何錯誤,則拋出異常,頂級循環顯示它,然後繼續下一個輸入行。

0

沒有一個正確的答案。
它是高度依賴於代碼和情況:

在你的情況上面的簡單的代碼(如果withing我自己的類),則錯誤代碼是罰款:

class MyClass 
{ 
    public: 
     void processesValidCodesOrIgnore(int code) 
     { 
      if (validate(code)) 
      { 
       processesCode(code); 
      } 
     } 
    private: 
     bool validate(int); 
     void processesCode(int); 
}; 

由於validate方法是私人的我知道它的結果總是會被檢查並且不被忽略,所以在這種情況下它很容易使用錯誤代碼。

另一方面,如果驗證是公開的,我肯定會考慮使用異常(取決於使用情況)。因爲這會迫使主叫方主動檢查問題而不是默默地忽略它們。