0.目錄
1.異常的最終處理
2.結束函數terminate()
3.小結
1.異常的最終處理
問題:
如果在main函數中拋出異常會發生什么?
如果異常不處理,最后會傳到哪里?
下面的代碼的輸出什么?
示例——異常的最終處理?:
#include <iostream>using namespace std;class Test
{
public:Test() {cout << "Test()"; cout << endl;}~Test() {cout << "~Test()"; cout << endl;}
};int main()
{static Test t;throw 1;return 0;
}
運行結果為:
[root@bogon Desktop]# g++ test.cpp
[root@bogon Desktop]# ./a.out
Test()
terminate called after throwing an instance of 'int'
Aborted (core dumped)
(不同編譯器的運行結果不同。)
2.結束函數terminate()
- 如果異常無法被處理,terminate() 結束函數會被自動調用
- 默認情況下,terminate() 調用庫函數 abort() 終止程序
- abort() 函數使得程序執行異常而立即退出
- C++支持替換默認的 terminate() 函數實現
terminate() 函數的替換:
- 自定義一個無返回值無參數的函數
- 不能拋出任何異常
- 必須以某種方式結束當前程序
- 調用 set_terminate() 設置自定義的結束函數
- 參數類型為
void (*) ()
- 返回值為默認的 terminate() 函數入口地址
- 參數類型為
示例1——自定義結束函數:
#include <iostream>
#include <cstdlib>
#include <exception>using namespace std;void my_terminate()
{cout << "void my_terminate()" << endl;exit(1);
}class Test
{
public:Test() {cout << "Test()"; cout << endl;}~Test() {cout << "~Test()"; cout << endl;}
};int main()
{set_terminate(my_terminate);static Test t;throw 1;return 0;
}
運行結果為:
[root@bogon Desktop]# g++ test.cpp
[root@bogon Desktop]# ./a.out
Test()
void my_terminate()
~Test()
將exit(1);
改為abort();
后的運行結果:
示例2——自定義結束函數:
void my_terminate()
{cout << "void my_terminate()" << endl;// exit(1);abort();
}
運行結果為:
[root@bogon Desktop]# g++ test.cpp
[root@bogon Desktop]# ./a.out
Test()
void my_terminate()
Aborted (core dumped)
(abort()函數是異常終止一個程序,并且異常終止的時候不會調用任何對象的析構函數。如果調用的是exit()函數,那么會確保所有的全局對象和靜態局部對象的析構函數被調用。)
面試題:
如果析構函數中拋出異常會發生什么情況?
示例——析構函數拋出異常:
#include <iostream>
#include <cstdlib>
#include <exception>using namespace std;void my_terminate()
{cout << "void my_terminate()" << endl;exit(1);
}class Test
{
public:Test(){cout << "Test()";cout << endl;}~Test(){cout << "~Test()";cout << endl;throw 2;}
};int main()
{set_terminate(my_terminate);static Test t;throw 1;return 0;
}
運行結果為:
[root@bogon Desktop]# g++ test.cpp
[root@bogon Desktop]# ./a.out
Test()
void my_terminate()
~Test()
Aborted (core dumped)
(析構函數中不能拋出異常,可能導致 terminate() 多次調用)
(不同編譯器之間在默認的 terminate() 函數實現上有差異。)
3.小結
- 如果異常沒有被處理,最后 terminate() 結束整個程序
- terminate() 是整個程序釋放系統資源的最后機會
- 結束函數可以自定義,但不能繼續拋出異常
- 析構函數中不能拋出異常,可能導致 terminate() 多次調用