1,來看下面這段代碼:
- #include <iostream>
- using namespace std;
- class BaseClass
- {
- public:
- BaseClass()
- {
- }
- };
- class MyClass : public BaseClass
- {
- private:
- char *ptr;
- public:
- MyClass();
- };
- MyClass::MyClass():BaseClass(), ptr(new char[10])
- {
- }
- int main()
- {
- MyClass c1;
- return 0;
- }
假設在MyClass的構造函數中需要處理記憶體配置設定錯誤,也就是new char[10]出錯,它會抛出std::bad_alloc異常,那麼應該怎麼捕獲它呢?想必也隻能将其移到構造函數體内:
- MyClass::MyClass() : BaseClass()
- {
- try
- {
- ptr = new char[10];
- }
- catch (const bad_alloc& ex)
- {
- }
- }
如果BaseClass的構造函數也抛出異常的話,這樣還是有問題的。這就是引入function-try-block的原因,通過它我們可以将try/catch的處理代碼放在構造函數中初始化清單的周圍,也就能夠捕獲由基類或成員變量構造函數抛出的任何異常了。
- #include <iostream>
- using namespace std;
- class BaseClass
- {
- public:
- BaseClass()
- {
- }
- };
- class MyClass : public BaseClass
- {
- private:
- char *ptr;
- public:
- MyClass();
- };
- MyClass::MyClass()
- try : BaseClass(), ptr(new char[10])
- {
- cout << "構造函數中" << endl;
- throw "error";
- }
- catch(const string& ex)
- {
- cout << "異常進行中" << endl;
- }
- int main()
- {
- MyClass c1;
- return 0;
- }
C++标準規定在構造函數和析構函數中,如果執行到達處理程式的末尾,在function-try-block的處理程式中捕獲的異常必須重新抛出。也就意味着上述代碼在運作時,會由于有未處理的異常而終止。
為什麼說标準這樣規定是必要的呢?因為在捕獲一個異常時,對象可能處于無效狀态,是以不能允許構造函數成功地完成,否則構造出的對象是不能確定其有效性的。
- int sum = 0;
- int x;
- while (cin >> x)
- {
- sum += x;
- }
- int sum = 0;
- for (int x; cin >> x;)
- {
- sum += x;
- }