C 如何允许程序中存在 BUG,却还能继续运行
Hello,大家好,欢迎来到“自由技艺“的学习小馆。今天我们就来聊一聊 C++ 中的异常机制吧。
在学校期间,我们很少会用得上异常机制。然而,工作之后,很多时候却不得不引入异常机制。因为一般情况下,使用函数的返回值来确定函数的运行状态有缺陷:比如有些函数返回1表示成功,有些函数返回0表示成功。而且,一旦用一个整型表示错误码,函数结果就不能返回了(当然用指针和引用可以解决)。
1 如何正确访问 vector 中指定下标的元素
#include <iostream>#include <vector>#include <stdexcept>int main() { std::vector<int> vec{1,2,3}; try { char val1 = vec[100]; //数组下标越界访问 std::cout << val1 << '\n'; } catch (std::exception e) { std::cout << '[1]out of bound!' << '\n'; } try { char val2 = vec.at(100); std::cout << val2 << '\n'; } catch (std::exception &e) { std::cout << '[2]out of bound!' << '\n'; }}
执行结果:
第一个 try 没有捕获到异常,输出了一个没有意义的字符(垃圾值)。因为[ ]不会检查下标越界,不会抛出异常,所以即使有错误,try 也检测不到。换句话说,发生异常时必须将异常明确地抛出,try 才能检测到;如果不抛出来,即使有异常 try 也检测不到。所谓抛出异常,就是明确地告诉程序发生了什么错误。
第二个 try 检测到了异常,并交给 catch 处理,执行 catch 中的语句。需要说明的是,异常一旦抛出,会立刻被 try 检测到,并且不会再执行异常点(异常发生位置)后面的语句。本例中抛出异常的位置是 at() 函数,它后面的 cout 语句就不会再被执行,所以看不到它的输出。
2 自定义异常消息
#include <iostream>#include <stdexcept>#include <vector>double f(int a, int b){ if (b == 0) { throw 'Division by zero'; } return (a/b);}int main() { try { int a = 10; int b = 0; int v = f(1, b); } catch (const char* msg) { std::cerr << msg << '\n'; } return 0;}
3 关键字 throw()
成员函数声明后面跟上throw(),表示告诉类的使用者:我的这个方法不会抛出异常,所以,在使用该方法的时候,不必把它至于 try/catch 异常处理块中。
声明一个不抛出异常的函数后,你有责任保证在你的函数的实现里面不会抛出异常。
最后,如果你想自定义一个异常,直接继承 exception 类,写个派生类即可。
#include <iostream>#include <stdexcept>#include <vector>class Myexception:public std::exception{};int f(int a, int b) throw() { if(b == 0) throw Myexception(); // 程序会在这里崩溃.(如果该异常被处理,不会崩溃) return a / b;}int main() { try { int a = 10; int b = 0; int v = f(1, b); } catch (const char* msg) { std::cerr << msg << '\n'; } return 0;}
执行结果:
赞 (0)