目錄
- 八、C++標準例外類
- 九、撰寫自己的例外類
- 十、繼承在例外中的應用
八、C++標準例外類
C++標準庫例外類繼承層次中的根類為exception,其定義在exception頭檔案中,它是C++標準庫所有函式拋出例外的基類,exception的介面定義如下:
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 類的直接派生類:
| 例外名稱 | 說 明 |
|---|---|
| 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 的派生類:
| 例外名稱 | 說 明 |
|---|---|
| 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函式和解構式
#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* ,
#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;
}
//結果:源空間為空!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/249682.html
標籤:C++
