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 }

 

标准库异常

/*未完待续*/

 

转载于:https://www.cnblogs.com/rivsidn/p/9315515.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值