c++的异常处理

版权声明:转载需注明出处,若有不足,欢迎指正。 https://blog.csdn.net/qq_28992301/article/details/53575030

c++的异常处理

1.异常处理的逻辑与顺序

异常处理对于代码来说,有点类似于goto

  • 异常处理的规律如下
    • 抛出异常后会直接跳转到异常处理块
    • throw可以在try语句块内任何地方,try后面必须紧跟catch
    • 若当前函数找不到可匹配的异常处理块,则异常会顺着函数的调用一层一层往外找,直到被处理为止,否则进程退出
    • 异常寻找异常处理块,是严格匹配类型的
    • 异常处理块类型相同时,是有优先级的,是从抛出异常开始往后找,最近的那个优先级高
    • 异常处理结束后,会接着执行异常处理块后面的代码
void MyFunc(void)
{
    try
    {
        throw 1;//抛出异常,异常值为1,类型为int
        cout << "1" << endl;//这句被跳过,不会执行
    }
    catch(int i)//严格匹配类型,异常值类型是int,并且该异常处理块离异常最近
    {
        cout << "int" << endl;//这句话被真正执行
    }
    catch(char i)//类型不匹配
    {
        cout << "char" << endl;//不执行
    }
    cout << "2" << endl;//这句话会被执行
}

int main(int argc, char *argv[])
{
    try
    {
        MyFunc();
    }
    catch(int i)//由于优先级太低,未被执行
    {
        cout << "in main" << endl;
    }
    cout << "3" << endl;//这句话会被执行
    return 0;
}

2.异常的重新解释

catch自己也能抛出异常,即将捕获的异常再次抛出。通过这个操作,可以实现异常的强制类型转换,这称之为异常的“重新解释”

try
{
    func(i);//假设是某个第三方库中的函数,其抛出的异常值十分晦涩,我们可以对其“重新解释”
}
catch(int i)//将异常“重新解释”为字符串后再次抛出
{
    switch(i)
    {
        case -1:
            throw "Invalid Parameter";
            break;
        case -2:
            throw "Runtime Exception";
            break;
        case -3:
            throw "Timeout Exception";
            break;
    }
}
catch(const char* cs)//正式进行异常处理
{
    cout << "Exception Info: " << cs << endl;
}

3.实际工程中的异常类

stl库中,提供了的异常类族

  • stl库中的异常类,都继承自父类exception。异常类有很多,分得很细,主要分为两个分支
    • logic_error:可避免的、明确的错误
    • runtime_error:无法避免,不可预知的错误
  • 有一点要注意,由于子类是父类的超集,子类异常可以被父类异常catch所捕获。所以在同时应用父子关系的异常类时,必须将子类异常catch放在前面,而父类异常catch放在后面。比如out_of_range是logic_error的子类,则必须如下使用:

try
{
    if(...)
        throw out_of_range("abcd");
    else
        throw logic_error("efgh");
}

catch(out_of_range e)
{
    cout << "Exception1" << endl;
}
catch(logic_error e)
{
    cout << "Exception2" << endl;
}

猜你喜欢

转载自blog.csdn.net/qq_28992301/article/details/53575030