C++標準庫異常類繼承層次中的根類爲exception,其定義在exception頭文件中,它是C++標準庫全部函數拋出異常的基類,exception的接口定義以下:ios
namespace std { class exception { public: exception() throw(); //不拋出任何異常 exception(const exception& e) throw(); exception& operator= (const exception& e) throw(); virtual ~exception() throw)(); virtual const char* what() const throw(); //返回異常的描述信息 }; }
先來看一下 exception 類的直接派生類:c++
異常名稱 | 說 明 |
---|---|
logic_error | 邏輯錯誤。 |
runtime_error | 運行時錯誤。 |
bad_alloc | 使用 new 或 new[ ] 分配內存失敗時拋出的異常。 |
bad_typeid | 使用 typeid 操做一個 NULL 指針,並且該指針是帶有虛函數的類,這時拋出 bad_typeid 異常。 |
bad_cast | 使用 dynamic_cast 轉換失敗時拋出的異常。 |
ios_base::failure | io 過程當中出現的異常。 |
bad_exception | 這是個特殊的異常,若是函數的異常列表裏聲明瞭 bad_exception 異常,當函數內部拋出了異常列表中沒有的異常時,若是調用的 unexpected() 函數中拋出了異常,不論什麼類型,都會被替換爲 bad_exception 類型。 |
logic_error 的派生類:dom
異常名稱 | 說 明 |
---|---|
length_error | 試圖生成一個超出該類型最大長度的對象時拋出該異常,例如 vector 的 resize 操做。 |
domain_error | 參數的值域錯誤,主要用在數學函數中,例如使用一個負值調用只能操做非負數的函數。 |
out_of_range | 超出有效範圍。 |
invalid_argument | 參數不合適。在標準庫中,當利用string對象構造 bitset 時,而 string 中的字符不是 0 或1 的時候,拋出該異常。 |
runtime_error 的派生類:函數
異常名稱 | 說 明 |
---|---|
range_error | 計算結果超出了有意義的值域範圍。 |
overflow_error | 算術計算上溢。 |
underflow_error | 算術計算下溢。 |
原則:建議繼承標準異常類,並重載父類的what函數和析構函數this
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include<stdexcept> using namespace std; class Person { public: Person() { mAge = 0; } void setAge(int age) { if (age < 0 || age > 100) { throw out_of_range("年齡應該在0-100之間!"); } this->mAge = age; } public: int mAge; }; //test01()使用標準庫的異常類,下面的exception能夠換爲out_of_range void test01() { Person p; try { p.setAge(1000); } catch (exception e) { cout << e.what() << endl; } } //本身寫個異常類,重載父類的what函數和析構函數 class MyOutOfRange : public exception { public: MyOutOfRange(const char* error) { pError = new char[strlen(error) + 1]; strcpy(pError, error); } ~MyOutOfRange() { if (pError != NULL) { delete[] pError; } } virtual const char* what() const { return pError; }; public: char* pError; }; void fun02() { throw MyOutOfRange("我本身的out_of_range!"); } void test02() { try { fun02(); } catch (exception& e) { cout << e.what() << endl; } } int main(void) { test01();//結果:年齡應該在0-100之間! //test02();//結果:我本身的out_of_range! return 0; }
異常儘可能拋個類對象(基類),不要再用 -1 或 char* 。spa
#define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std; //異常基類 class BaseMyException { public: virtual void what() = 0; virtual ~BaseMyException() {} }; class TargetSpaceNullException : public BaseMyException { public: virtual void what() { cout << "目標空間空!" << endl; } ~TargetSpaceNullException() {} }; class SourceSpaceNullException : public BaseMyException { public: virtual void what() { cout << "源空間爲空!" << endl; } ~SourceSpaceNullException() {} }; void copy_str(char* taget, char* source) { if (taget == NULL) { throw TargetSpaceNullException(); } if (source == NULL) { throw SourceSpaceNullException(); } //int len = strlen(source) + 1; while (*source != '\0') { *taget = *source; taget++; source++; } } int main(void) { const char* source = "abcdefg"; char buf[1024] = { 0 }; try { copy_str(buf, NULL); } catch (BaseMyException& ex) { ex.what(); } cout << buf << endl; return 0; } //結果:源空間爲空!