自訂例外類別


您可以自訂一個例外類別,以處理特定的錯誤狀況,在C++中鼓勵您將例外定義為一定的類別階層體系,例如先定義一個Exception類別為基底類別:
  • Exception.h
#ifndef EXCEPTION
#define EXCEPTION

class Exception {
public:
Exception() {
}

Exception(const char *message) : _message(message) {
}

virtual const char* message() {
return _message;
}

protected:
const char *_message;
};

#endif

假設您要定義一個安全的陣列類別,例如 建構 函式、解構函式 中定義的SafeArray類別,您希望在陣列存取超過陣列長度時丟出一個ArrayIndexOutOfBoundsException,您可以如下繼 承Exception類別並定義:
  • ArrayIndexOutOfBoundsException.h
#include "Exception.h"

class ArrayIndexOutOfBoundsException : public Exception {
public:
ArrayIndexOutOfBoundsException(int);

ArrayIndexOutOfBoundsException(const char *message) {
_message = message;
}

virtual const char* message() {
return _message;
}
};

  • ArrayIndexOutOfBoundsException.cpp
#include "ArrayIndexOutOfBoundsException.h"
#include <string>
#include <sstream>
using namespace std;

ArrayIndexOutOfBoundsException::ArrayIndexOutOfBoundsException(int index) {
string str1;
stringstream sstr;
sstr << index;
sstr >> str1;
string str2("ArrayIndexOutOfBoundsException:");
str2.append(str1);
_message = str2.c_str();
}

stringstream可用於基本型態與string型態的轉換,您將基本型態導入stringstream,再將之導至string中,接著重新定義 SafeArray.cpp中的get()與set()函式如下:
  • SafeArray.cpp
#include "SafeArray.h"
#include "ArrayIndexOutOfBoundsException.h"

// 動態配置陣列
SafeArray::SafeArray(int len) {
length = len;
_array = new int[length];
}

// 測試是否超出陣列長度
bool SafeArray::isSafe(int i) {
//
if(i >= length || i < 0) {
return false;
}
else {
return true;
}
}

// 取得陣列元素值
int SafeArray::get(int i) {
if(isSafe(i)) {
return _array[i];
}
else {
// 存取超過陣列長度,丟出例外
throw ArrayIndexOutOfBoundsException(i);
}
}

// 設定陣列元素值
void SafeArray::set(int i, int value) {
if(isSafe(i)) {
_array[i] = value;
}
else {
// 存取超過陣列長度,丟出例外
throw ArrayIndexOutOfBoundsException(i);
}
}

// 刪除動態配置的資源
SafeArray::~SafeArray() {
delete [] _array;
}

在陣列存取超過陣列長度時丟出一個ArrayIndexOutOfBoundsException,您可以如下使用try...catch來捕捉例外:
  • main.cpp
#include <iostream> 
#include "SafeArray.h"
#include "Exception.h"
#include "ArrayIndexOutOfBoundsException.h"
using namespace std;

int main() {
SafeArray safeArray(10);

try {
// 故意存取超過陣列長度
for(int i = 0; i <= safeArray.length; i++) {
safeArray.set(i, (i + 1) * 10);
}

for(int i = 0; i < safeArray.length; i++) {
cout << safeArray.get(i) << " ";
}

cout << endl;
}
catch(ArrayIndexOutOfBoundsException e) {
cout << endl
<< e.message()
<< endl;
}
catch(Exception e) {
cout << endl
<< e.message()
<< endl;
}

return 0;
}

執行結果:
ArrayIndexOutOfBoundsException:10

在try...catch的最後一個catch您捕捉了Exception型態的例外,這可以捕捉所有Exception及其子類別的例外,這避免了直接 使用catch(...)來一網打盡式的捕捉例外的方式。