【《C++ Primer Plus》读书笔记】异常

abort()

直接终止程序,提示信息

exit()

刷新文件缓冲区,但是不提示消息

try, throw, catch

一个try可以跟多个catch;

throw的原理:
执行throw终止函数的执行,导致程序沿函数的调用序列后退,直到找到包含try块的函数。
(这里是否是,编译器如果看到try语句,就把try块内所有执行的语句结果都压栈保护现场呢?)
看了栈解退的机理好像不是这样,遇到throw语句,栈将所有的中间变量释放,然后程序跳转到try块的返回地址,可以理解为try块结束的‘}’,(实际上也就是由这个‘}’去释放中间变量)

如果仅有throw语句而没有catch,默认情况下程序将异常终止;

一个catch, 多个try?

是不可以的,因为try之后一定要有一个异常处理


如果任性一点,想throw什么throw什么的话,那catch的参数就变成了…

    throw "whatever it is";

    catch(...) {
        do something    
    }

exception类

基类是exception类;但是在C++标准库中定义了很多对应于不同异常情况的子类,这些子类继承exception基类。
这种就是我们throw一个子类,然后catch的时候参数可以是子类,也可以是基类。

其实我觉得标准库包含的exception有点多余了….可能是为了标准统一化吧,因为能抛出的错误比起我们遇到的错误实在有限,我们更常用的是利用这个接口去自己实现子类
如:

class bad_bad():public exception {
    public:
        const char* what() {
            return "......";
        }
}

问题:

我们在写python的时候经常会用到:

    try:
        do something
    except:
        do other things

我就在想c++里面我们是不是在包含了< exception >头文件之后直接也像python那样:

    try {
        do something
    }
    catch (exception & e) {
        cout << e.what() << endl;
    }

这样不用throw而让程序自动去throw呢?发现不行
那我们该怎么用呢?必须自己定义一个exception的对象,然后自己抛出?

我百度了一下搜到这个帖子:
http://bbs.csdn.net/topics/390690361

感觉三楼说的很对:

所有C++ try block后面catch到的exception都必须有对应的throw, 没有throw, 就没东西可catch。所以像divide by zero, access violation都是catch不到的,不管你try的多么hard :)

关于这一点,我跟同学讨论,也自己试了一下,其实有些是可以抛出的(这些应该是包含在标准库内的):

    int * a;
    try {
        a = new int [100000000000000000];
    }
    catch(exception & e) {
        cout << "下一行是自己定义的" << endl;
        cout << e.what() << endl;
    }

g++返回:

wenshuaigedeAir:Syntax macbookair$ ./a.out
a.out(32053,0x7fff742da300) malloc: *** mach_vm_map(size=400000000000000000) failed (error code=3)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
下一行是自己定义的
std::bad_alloc

但是这样的很少,divide by zero还是不能抛出,所以我们还是尽量去自己定义错误,通过exception这个基类的接口去实现;

但是在try块里检测错误并throw是错误的做法,应该是try块里调用的函数(包括成员函数)有责任检测异常并适当地throw。


所以之前写程序在函数内发现在处理异常的时候,要退出函数,但是返回值类型不符呀,所以很困扰,原来正确的处理方法是抛出一个异常。

写个简单的代码示意:


double divide(int a, int b) {
    if (b == 0) throw "whatever it is";
    else return a/b;
}

try {
    double a = divide(1, 0);
} catch (...) {
    do something
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值