c++ 异常

try...catch 中,控制权如何从 try块 转移到 catch块?

1.使用 throw 表达式将临时对象 temp 初始化为 Exception Type temp {theException};

2.在 try 块中定义的所有自动对象调用析构函数【将在try中声明的局部变量释放掉】

3.选择参数类型与异常类型匹配的第一个处理程序

4.使用异常的副本把参数初始化为 typeN ex(temp);并把控制权传递给处理程序

5.除非处理程序中的代码决定结束程序,否则在处理程序执行完之后,将继续执行 try 块的最后一个处理程序后面的语句。

 

异常处理流程【程序中的 try...catch 必须是仅挨着的,类比 if...else... 】

try {
    /*code that may throw exceptions*/
}

catch (parameter specifying exception type 1) {
    /*handle the exception*/
}

catch (parameter specifying exception type 2) {
    /*handle the exception*/
}

catch (parameter specifying exception type 3) {
    /*handle the exception*/
}

 

try 中 throw 不同类型的 exception 对应后边不同的 catch,catch 相同类型的 exception 时只匹配最前边的。

int main()
{
    try {
        if (0)
            throw 1;
        if (0)
            throw "test";

        if (1)
            throw 1.0;
    }
    
    catch (int i) {
        std::cout << 4 << std::endl;
        return -1;
    }
    catch (const char* message) {
        std::cout << 5 << std::endl;
        return -1;
    }
    catch (double x) {
        std::cout << 6 << std::endl;
        return -1;
    }

    std::cout << "test" << std::endl;
    
    return 0;
}

当上边的 catch 匹配上之后,如果不 return ,下边的 catch 同样不会执行,但是 catch 之后的语句会正常执行。

 

try块的嵌套

int main()
{
    try {
        try {
            throw "test";
        }

        catch(int i) {
            std::cout << 1 << std::endl;            
        }
    }
    
    catch(const char* message) {
        std::cout << 2 << std::endl;
    }
    
    return 0;
}

 catch中的变量何时调用析构函数

class Trouble {
    private :
        std::string message;
    public :
        Trouble(std::string str = "there's a problem") : message {str} {std::cout << "constructor" << std::endl;}
        ~Trouble() {std::cout << "destructor" << std::endl;}

        std::string what() const {return message;}
};


int main()
{
    try {
        throw Trouble{};
    }
#if 0    //case 0
    catch (const Trouble t) {
#else    //case 1
    catch (const Trouble& t) {
#endif
        std::cout << t.what() << std::endl;
    }
    
    return 0;
}

 

 case 0:

$ ./exceptions
constructor
there's a problem
destructor    //复制的对象,不需要调用构造函数,多调用了一次析构函数
destructor


case 1:

$ ./exceptions
constructor
there's a problem
destructor
【相当于是传递参数,如果传递的参数是引用则不需要重新创建,参见 本博客:c++构造函数和析构函数 第三个demo】

 

抛出异常的函数,不抛出异常的函数

//不会将所有异常全部catch掉
void
doThat(int argument) try { //code for the funticon } catch () { //Handler code for the exceptions }
//能够catch所有异常,不让异常抛出
void doThar(int argument) noexcept try { //code for the funticon } catch () { //Handler code for the exceptions }

 

标准库异常

/*未完待续*/

 

posted on 2018-07-16 15:01  rivsidn  阅读(96)  评论(0编辑  收藏  举报

导航