C++ 異常機制(下)

8、C++標準異常類

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 算術計算下溢。

9、編寫本身的異常類

原則:建議繼承標準異常類,並重載父類的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;
}

10、繼承在異常中的應用

異常儘可能拋個類對象(基類),不要再用 -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;
}
//結果:源空間爲空!
相關文章
相關標籤/搜索