3. 自定义异常类型

上述示例中我们使用 const char * 类型的错误信息来表示 索引超出范围这样的一种错误,这种方法虽然可行,当容易产生混乱,因此 C++ 建议为每一种错误定义一种专门表式此种错误的类型。这样便于区分和处理。

以下自定义 RangeError 类型的错误来描述 MyRange 类索引超出范围这样类型的错误如下:

class RangeError {
    public:
        RangeError(const string &msg) : message(msg) {}
        const string & get_message() const {return message;}
    private:
        string message;
};

示例

以下是完整的代码

/ filename: custom_excep_type.cpp
#include <iostream>

using namespace std;

class RangeError {
    public:
        RangeError(const string &msg) : message(msg) {}
        const string & get_message() const {return message;}
    private:
        string message;
};

class MyRange{
    public:
        MyRange(int begin, int end, int stp=1): start(begin), stop(end), step(stp) {}
        // 重载 [] 运算符
        int operator [] (int index) {
            int value = start + index * step;
            if (index < 0)
                throw RangeError("索引不能为负数值");
            if (step > 0 && value > stop)
                throw RangeError("索引越界");
            else if (step < 0 && value < stop)
                throw RangeError("索引越界");

            return value;
        }
    private:
        int start;
        int stop;
        int step;
};

int main(int argc, char * argv[]) {
    MyRange r2(1, 10, 3);  // 生成 1、4、7

    try{
        cout << r2[0] << endl;  // 打印 1
        cout << r2[1] << endl;  // 打印 4
        cout << r2[-1] << endl;  // 抛处 RangeError 类型的错误
        cout << r2[100] << endl;  // 抛处 RangeError 类型的错误
    }
    catch (const RangeError &err) {
        cout << "捕获 RangeError 类型的错误: " << err.get_message() << endl;
        cout << "错误已经处理,程序进入正常状态!" << endl;
    }
    catch (...) {
        cout << "捕获其他类型的错误并处理" << endl;
    }
    printf("程序正常退出!\n");

    return 0;
}

编译和运行结果如下:

weimz@mzstudio:~$ g++ -o custom_excep_type custom_excep_type.cpp
weimz@mzstudio:~$ ./custom_excep_type 
1
4
捕获 RangeError 类型的错误: 索引不能为负数值
错误已经处理,程序进入正常状态!
程序正常退出!