發新話題

C++ Gossip - 物件導向《例外處理》 自訂例外類別

C++ Gossip - 物件導向《例外處理》 自訂例外類別

您可以自訂一個例外類別,以處理特定的錯誤狀況,在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;        
    }
    else {
        // 存取超過陣列長度,丟出例外
        throw ArrayIndexOutOfBoundsException(i);         
    }
}

// 設定陣列元素值
void SafeArray::set(int i, int value) {
    if(isSafe(i)) {
        _array = 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(...)來一網打盡式的捕捉例外的方式。

TOP

發新話題

本站所有圖文均屬網友發表,僅代表作者的觀點與本站無關,如有侵權請通知版主會盡快刪除。