2017-05-23 83 views
0

我有一個疑問關於錯誤處理...如果從在其他函數內調用的函數拋出異常,會發生什麼情況?

如果一個函數拋出一個異常,並且在主程序中沒有捕獲到異常將會崩潰。

我的問題是爲什麼這個程序不會崩潰?如果從Test函數enterNumber拋出異常,即使它沒有被捕獲也會拋出異常?

不應該把每個可能拋出異常的函數放在try-catch塊中,以防萬一拋出異常嗎?

#include <iostream> 
    #include <stdexcept> 

    void Test(int number) { 
     if(number < 0) 
      throw std::domain_error("Number is negative"); 
    } 

    int enterNumber() { 
     int number; 
     std::cout << "Enter a number: "; 
     std::cin >> number; 
     Test(number);   
     return number; 
    } 

    int main() { 
     try { 
      int number = enterNumber(); 
      std::cout << "Entered number: " << number; 
     } 
     catch(std::domain_error e) { 
      std::cout << e.what(); 
     } 
     return 0; 
    } 

我認爲應該這樣寫:

void Test(int number) { 
    if(number < 0) 
     throw std::domain_error("Number is negative"); 
} 

int enterNumber() { 
    int number; 
    std::cout << "Enter a number: "; 
    std::cin >> number; 
    try { 
     Test(number); 
    } 
    catch(...) { 
     throw; 
    } 
    return number; 
} 

int main() { 
    try { 
     int number = enterNumber(); 
     std::cout << "Entered number: " << number; 
    } 
    catch(std::domain_error e) { 
     std::cout << e.what(); 
    } 
    return 0; 
} 

如果有人可以解釋的功能enterNumber如何拋出異常的情況下,Test拋出它? (情況1°)

謝謝:)

+1

按照C++設計工作。一個未被捕獲的函數使堆棧起泡。 –

+1

例外可以讓功能冒出來。這是問題的主要原因之一。如果你沒有冒出主線,那麼你很好。 – NathanOliver

+1

您的'嘗試{(number); } catch(...){ throw;'構造是完全沒有意義的。你捕獲所有的異常,只是立即重新拋出它們 - 就像你剛剛刪除了'try' /'catch'一樣。 –

回答

1

你並不需要趕上從調用導致異常的功能的功能異常。事實上,最好的做法是儘可能地(但不能進一步)從拋出異常的網站上捕捉異常,因爲只有在程序的更高層次上,您纔有足夠的信息來產生有意義的錯誤消息,並且/或以其他方式處理例外情況。但是,該例外應該在程序的一些級別捕獲,否則程序將以不受控制的方式終止。

+0

對於一些例外情況,讓它們逃離主程序並關閉程序也可以非常好。有時候最好是崩潰(併爲後來的調試寫一個核心),而不是試圖從破碎的世界中恢復,並可能造成更多的傷害。 –

+1

*「最好的做法是儘可能地從拋出異常的地方捕捉異常」*這對我來說看起來不太合適,這意味着抓住'main'或線程的主要功能是最好的地方捕捉異常。也許像「最佳實踐就是隻在可以對此做些什麼的情況下才能發現異常」或類似的情況。 –

+0

@弗朗索瓦我說「儘可能」 - 捕捉並處理主要內容都是不可能的。我已經稍微明白了答案。 –

相關問題