天天看點

C++ Exercises(二十)

1,來看下面這段代碼:

  1. #include <iostream>  
  2. using namespace std;  
  3. class BaseClass  
  4. {  
  5. public:  
  6.     BaseClass()  
  7.     {  
  8.     }  
  9. };  
  10. class MyClass : public BaseClass  
  11. {  
  12. private:  
  13.     char *ptr;  
  14. public:  
  15.     MyClass();  
  16. };  
  17. MyClass::MyClass():BaseClass(), ptr(new char[10])  
  18. {  
  19. }  
  20. int main()  
  21. {  
  22.     MyClass c1;  
  23.     return 0;  

   假設在MyClass的構造函數中需要處理記憶體配置設定錯誤,也就是new char[10]出錯,它會抛出std::bad_alloc異常,那麼應該怎麼捕獲它呢?想必也隻能将其移到構造函數體内:

  1. MyClass::MyClass() : BaseClass()  
  2. {  
  3.     try 
  4.     {  
  5.         ptr = new char[10];  
  6.     }  
  7.     catch (const bad_alloc& ex)  
  8.     {  
  9.     }  

    如果BaseClass的構造函數也抛出異常的話,這樣還是有問題的。這就是引入function-try-block的原因,通過它我們可以将try/catch的處理代碼放在構造函數中初始化清單的周圍,也就能夠捕獲由基類或成員變量構造函數抛出的任何異常了。

  1. #include <iostream>  
  2. using namespace std;  
  3. class BaseClass  
  4. {  
  5. public:  
  6.     BaseClass()  
  7.     {  
  8.     }  
  9. };  
  10. class MyClass : public BaseClass  
  11. {  
  12. private:  
  13.     char *ptr;  
  14. public:  
  15.     MyClass();  
  16. };  
  17. MyClass::MyClass()  
  18. try : BaseClass(), ptr(new char[10])  
  19. {  
  20.     cout << "構造函數中" << endl;  
  21.     throw "error";  
  22. }  
  23. catch(const string& ex)  
  24. {  
  25.     cout << "異常進行中" << endl;  
  26. }  
  27. int main()  
  28. {  
  29.     MyClass c1;  
  30.     return 0;  

   C++标準規定在構造函數和析構函數中,如果執行到達處理程式的末尾,在function-try-block的處理程式中捕獲的異常必須重新抛出。也就意味着上述代碼在運作時,會由于有未處理的異常而終止。

      為什麼說标準這樣規定是必要的呢?因為在捕獲一個異常時,對象可能處于無效狀态,是以不能允許構造函數成功地完成,否則構造出的對象是不能確定其有效性的。

  1. int sum = 0;  
  2. int x;  
  3. while (cin >> x)  
  4. {  
  5.     sum += x;  
  1. int sum = 0;  
  2. for (int x; cin >> x;)  
  3. {  
  4.     sum += x;  

繼續閱讀