程序异常的概念
主要是指出现了一些很少发生或者出乎意料的状态,通常显示一个程序的错误或者要求一个必须回应的。如果不能满足这个回应则会经常造成程序卡死不能进行相应的处理。
c语言里面有几个异常管理机制,这些标准在c++里面也可以用,但是c++设计了更加方便的基本不可见处理方式。
使用try与catch块就可以实现对程序异常的捕捉和处理,但是注意的是一定要保证所有的异常的类型和抛出异常类型的一致,不然就很难捕捉得到。在catch里面添加需要捕捉的内容,之后在try里面加入所有需要检验是否抛出异常的代码。
绝对终止机制
这是一种彻底忽略异常的方法,使用一种安全的退出方法,在一些情形里面是最正确的方法,c库文件提供两个不是相当完美的程序函数。abort还有exit这两个函数都不是将程序交还给用户处理而是字节中子程序交还给系统。
- abort:这是默认的,在运行的时候诊断里调用abort来安全结束程序,这种结束方式可能不会刷新与关闭打开的文件,或者删除临时文件爱你,与你的设计有关。
- exit:附加了关闭打开的文件与返回状态码给执行环境,并且调用atexit注册的返回函数
通常是很重大程序失败会调用abort函数,原因abort默认行为是立即结束程序,需要在调用abort之前保存数据。
对于exit函数执行的回调函数其实是按照注册顺序的逆序调用的
有条件的结束程序
可以使用断言
assert函数,一般定义在assert.h文件里面,在断言函数里面不能有实质性的动作,一般只是做些比较与判断就好。否则调试和发布版会有很大区别
非局部GOTO机制
setjmp和longjmp可以跨越函数,因为共同是不可以跨越函数的,但是异常处理是可以跨越函数的。
异常申明
申明c++函数申明的一种,指定了函数可以抛出什么异常
c++标准库
里面介绍的关于异常的部分的内容
error_code类里面大致内容
namespace std{
class error_code{
public:
const error_category& category() const noexcept;
int value() const noexcept;
string message() const noexcept;
explicit operator bool() const noexcept;
error_condtion default_error_condtion() const noexcept;
};
}
noexcept修饰符的作用
noexcept形如其名地,表示其修饰的函数不会抛出异常。
在C++11中如果noexcept修饰的函数抛出了异常,编译器可以选择直接调用std::terminate()函数来终止程序的运行,这比基于异常机制的throw()在效率上会高一些。
这是因为异常机制会带来一些额外开销,比如函数抛出异常,会导致函数栈被依次地展开(unwind),并依帧调用在本帧中已构造的自动变量的析构函数等
error_category类的内部结构(部分)
namespace std{
class error_category{
public:
virtual const char * name() const noexcept;
virtual string message() const noexcept;
virtual error_condition default_error_condition(int ev)
bool operator==(const error_category& rts) const noexcept;
bool operator!=(const error_category& rts) const noexcept;
...
};
}
name函数:返回分类名称
message函数:返回传入值的响应信息
default_error_condition:默认的差错状态
使用方式
举一个泛型函数来处理不同的异常
#include <exception>
#include <system_error>
#include <future>
#include <iostream>
std::exception_ptr eptr;
template <typename T>
void processCodeException (const T& e)
{
using namespace std;
auto c = e.code();
cerr << "-category : " << e.category().name() << endl;
cerr << "-value : " << e.value() < endl;
cerr << "-msg : " << e.message() << endl;
cerr << "-def category : " << e.default_error_condition().category().name() << endl;
cerr << "-def mes : " << e.default_error_condition().message();
cerr << "-def value : " << e.default_error_condition().value();
}
void processExecption()
{
using namespace std;
try{
...
}
catch(const system_error & e){
cerr << "SYSTEM EXCEPTION :" << e.what() << endl;
processCodeException(e);
//或者也可以使用current_exception
eptr = std::current_exception();
//如果需要在某个场景重新抛出这个异常的话也可以使用rethrow_exception
std::rethrow_exception(eptr);
}
}
参考资料:
https://baijiahao.baidu.com/s?id=1611302717509096034&wfr=spider&for=pc