三十一、C++的异常处理
1、什么是异常:
当代码出错时,停止执行,返回一个数据
C语言中调用者只能通过使用、接收返回值的方式处理错误、异常
C++中可以接收自己返回或者系统返回的返回值,根据返回数据的类型不同,从而执行不同的错误、异常处理语句
2、如何抛异常
throw 数据;
数据可以是任何类型,不要去抛局部变量的地址或者引用
3、如何捕获异常
try
{
//可能会产生异常的代码或者函数调用
}
catch(类型名& 变量名)
{
//处理问题
}
4、异常说明
返回值 函数名(参数列表) throw(类型1,类型2,...)
{
}
异常说明相当于该函数的限制或者承诺,只能抛出说明过的异常类型,如果函数抛出
了异常说明外的异常类型,运行时无法捕获并产生运行错误
5.标准异常
C++中已经定义好的异常类,当对应的异常发生后,会自动抛出定义好的异常对象
exception 该异常是所有标准 C++ 异常的父类。
bad_alloc 该异常可以通过 new 抛出。(内存不足),如果是C++11会抛出 bad_array_new_length
bad_cast 该异常可以通过 dynamic_cast 抛出。
bad_exception 这在处理 C++ 程序中无法预期的异常时非常有用。
bad_typeid 该异常可以通过 typeid 抛出。
logic_error 理论上可以通过读取代码来检测到的异常。
6.自定义异常类
class ZZError
{
string time;
string file;
string func;
size_t line;
string erro;
public:
ZZError(const string& time,const string& file,const string& func,const size_t& line,
const string& erro):time(time),file(file),func(func),line(line),erro(erro) {}
friend ostream& operator<<(ostream& os,ZZError& err)
{
return os << "time:"<< err.time << " file:" << err.file << " func:" << err.func <<
" line:" << err.line << " erro:" << err.erro;
}
};
7.使用异常需要注意的问题
1.不要返回局部变量、对象的地址,但可以返回临时变量
2.建议都用引用的方式进行捕获异常,否则会构造、拷贝两次
3.不要在构造函数、析构函数抛异常
4.如果存在父子类异常,先捕获子类,在捕获父类