C异常处理:
- 1、直接终止程序,比如在除法算式里面讲除数不小心给成了0.
- 2、返回一个能够表示错误的值,附加错误码。
- 3、调用一个已经准备好的错误情况下调用的函数。
- 4、暴力解决的方式,直接将程序使用return或者exit退出。
- 5、使用goto语句进行跳转。
- 6、使用setjmp()和longjmp().
注意:
- 1、setjmp()和 longjmp()必须先调用,在异常的位置通过先调用longjmp以先回复先前被保存的程序的执行点,否则将导致不可预测的结果,甚至崩溃。
- 2、在调用的setjmp()的函数返回之前调用longjmp,否则结果将出现不可预料的结果。
setjmp()和longjmp()存在的缺陷:
- 1、函数的使用者必须非常靠近函数调用的位置编写错误处理代码,无疑是代码变得很臃肿笨拙。
- 2、setjmp()和longjmp()并不能够很好的支持C++面向对象的语义。
举个栗子:
jmp_buf mark;
void FunTest1()
{
longjmp(mark, 1);
}
void FunTest2()
{
longjmp(mark, 2);
}
void FunTest3()
{
longjmp(mark, 3);
}
int main()
{
int iState = setjmp(mark);
if (0 == iState)
{
FunTest1();
FunTest2();
FunTest3();
}
else
{
switch(iState)
{
case 1:
cout<< "FunTest1() Error"<<endl;
break;
case 2:
cout<< "FunTest2() Error"<<endl;
break;
case 3:
cout<< "FunTest3() Error"<<endl;
break;
}
}
cout<< "Main End"<<endl;
return 0;
}
C++异常处理:异常:当一个函数发现自己无法处理的错误时抛出异常,让函数的调用者直接或者间接地处理这个问题。
异常的抛出和捕获
- 1、异常是通过抛出对象而引发的,该对象的类型决定了应该激活哪个处理码。
- 2、被选中的处理代码是调用链中与该对象类型匹配且离抛出异常位置最近的那一个。
- 3、抛出异常后常会释放局部存储的对象,所以被抛出的对象也就还给了系统,throw表达式会初始化一个抛出后的异常对象的副本,异常对象由编译管理,异常对象在传给对应的catch处理之后撤离。
异常捕获的匹配规则异常对象的类型与catch说明符的类型必须完全匹配。只有以下几种情况例外
- 1. 允许从非const对象到const的转换。
- 2. 允许从派生类型到基类类型的转换。
- 3. 将数组转换为指向数组类型的指针,将函数转换为指向函数类型的指针。
异常的重新抛出有可能单个的catch不能完全处理一个异常,在进行一些校正处理以后,希望再交给更外层的调用链函数来处理,catch则可以通过重新抛出将异常传递给更上层的函数进行理。
异常规范在函数声明之后,列出该函数可能抛出异常类型,并保证该函数不会抛出其他类型的异常。
- 1、成员函数在类内声明和类外定义两处必须有相同的异常规范。
- 2、函数抛出一个没有被列在它异常规范中的异常时(且函数中抛出异常没有在函数内部进行处理),系统调用C++标准库中定义的函数unexpected().
- 3、如果异常规范为throw(),则表示不得抛出任何异常,该函数不用放在try块中。
- 4、派生类的虚函数的异常规范必须与基类虚函数的异常规范一样或更严格(是基类虚函数的异常的子集)。
因为:派生类的虚函数被指向基类类型的指针调用时,保证不会违背基类成员函数的异常规范。
举个栗子:
class Exception
{
public :
Exception(int errId = 0, const char * errMsg = "" )
: _errId(errId )
, _errMsg(errMsg )
{}
void What () const
{
cout<<"errId:" <<_errId<< endl;
cout<<"errMsg:" <<_errMsg<< endl;
}
private :
int _errId ; // 错误码
string _errMsg ; // 错误消息
};
void Func1 ()
{
throw string ("Throw Func1 string");
}
void Func2 ()
{
try
{
Func1();
}
catch(string & errMsg)
{
cout<<errMsg <<endl;
}
}
void Func3 ()
{
try
{
Func2();
}
catch (Exception & e)
{
e.What ();
}
}