c++异常处理note

概述

当抛出一个异常后,程序暂停当前函数的执行过程并立即开始寻找与异常匹配的catch语句,这叫栈展开。如果找不到,最后会调用标准库函数terminate

自动销毁

栈展开的时候,在该块里面的局部变量将进行销毁,如果是类,会调用析构。所以说才要尽量使用智能指针,就不用在finally里面写delete了。

异常对象

其实可以throw任何对象,这个对象会被保存在编译器管理的空间中,确保无论是哪个地方catch了,都能访问到这个对象。也可以throw出任何数组和函数,会被编译器转化为指针。
但是,一般不要直接甩出来一个对象,否则这个对象在throw之前会被析构一次,传到catch之后又会析构一次,很蠢。

重新抛出

在catch块里面,单单写这么一句就可以重新抛出

throw;

捕获所有异常

类似于Java在最后写

catch(Exception e){

}

c++版本的写法是

catch(...){}

同样一般是放在最后

捕获构造函数异常

直接用try catch包起来

class A{
public:
    A() try : arg(arg){

    } catch(){

    }
}

noexcept

说明这个函数不会抛错误,对编译器来说大有好处,能够执行一些特殊的优化。
但是就算是写了这个,也可以真的抛出异常,只是程序会直接terminate。

运算符

noexcept(func()); // true代表这个函数不会抛出异常

异常层级

这里写图片描述

扫描二维码关注公众号,回复: 2769559 查看本文章

自定义的exception一般要继承于runtime_error或者logic_error
定义explicit的构造函数传入一个string,并透传到上一级的构造函数里面去。

Cautious
在throw那个语句临时创建的对象,只会执行一次构造函数,不会马上析构,等到catch执行完之后才会进行析构。假若是先新建了一个对象,然后再将其抛出,那么在抛出之前就会进行一次析构,然后抛出去之后再在catch里面析构一次,会造成不可预估的后果。

class CustomException : runtime_error{
public:
    explicit CustomException(const string& what) : runtime_error(what){
        cout << "CustomException()" << endl;
    }
    const char* getMsg(){
        return this->what();
    }
    virtual ~CustomException(){
        cout << "~CustomException()" << endl;
    }
};

void func()
{
    throw CustomException("msg content");
}

int _tmain(int argc, _TCHAR* argv[])
{
    try{
        func();
    }
    catch (CustomException &e){
        cout << "error: " << e.getMsg() << endl;
    }

    system("pause");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/hhh132/article/details/81355550