摘要:本文主要向大家介绍了VC编程之备忘:VC++ 中的异常处理,通过具体的内容向大家展示,希望对大家学习VC编程有所帮助。
本文主要向大家介绍了VC编程之备忘:VC++ 中的异常处理,通过具体的内容向大家展示,希望对大家学习VC编程有所帮助。
当程序遇到一个异常或一个严重的错误时,通常意味着它不能继续正常运行并且需要停止执行。任何的设计都离不开对异常与错误的处理。如果设计者不主动规避程序异常,往往在程序发生异常时,会被系统终止而直接退出。这对使用者来说,是很不友好的。
如果主动处理异常,可以显式地提示错误地发生,也可以避免程序异常终止。更好的处理是,在设计时,预估一些错误,让用户避开这些错误以让程序顺利运行。对一些无法预知的异常,也需要我们通过VC++的异常处理机制,显式地告诉错误已发生,并保证程序的继续进行。
VC++提供了两种不同性质的异常处理: 结构化异常SEH (Structured Exception Handling, ) 和 类型化的 C++异常。 SEH 是VC++编译器特有的,因此如果你想要编写可移植的代码,就不应当使用SEH。他只能在 Windows系统中产生作用。如果只想编写 Windows 应用。那么,最好选择SEH来处理异常。SEH 比 类型化的C++异常 更方便,更灵活。
结构化异常SEH
__try,__except,__finally 是Windows系列操作系统平台上提供的SEH的处理模型。
__try,__except:表示 try {}语句中发生异常,将转到 except () {}模块执行。如果try{}没有异常。except模块被跳过。继续执行 except {} 之后的代码。
__try, __finally : 表示try {}语句无论有没异常发生,finally{}模块都会被执行。__try __finally 没有太多用法,不作详细说明。只要用对地方就行了。
___leave : 一般用在 try{} 里。表示退出 try 模块,并不执行 leave之后的语句。根当于函数中的return. 不过,这里只退出try{}.
__try,__except 简单用法示范:
int _tmain(int argc, _TCHAR* argv[])
{
int v1, v2;
v1 = 1; v2 = 0;
double x=0;
__try
{
// if (v2==0) ___leave;
// 加上___leave这一句。leave 之后的代码都不会执行 跳出 try 执行 try except 之后的代码。
x = v1 / v2; // x = myFunc(v1, v2);
cout << x << endl;
}
__except (1) // 试着改为 0 或 -1 看看效果
{
cout << "Error!" << endl;
}
system("pause");
return 0;
}
__except 后的括号里,是一个表达式或一个数值。表达式返回的也应是一个数值。这个数值 为 1-3 表明 except的三种处理方试:
__except(-1) 异常终止,退出程序。很少用这个。除非人为想终止自己的程序。
__except(0) 跳出当前异常,继续由下一个异常 except 来处理。
__except(1) 接受异常。执行异常 {} 中的语句。以上二个值 -1, 0 都不会执行 except{ ... } 中的语句。
这三个值,在 Windows 中,有三个常量代表:
EXCEPTION_CONTINUE_EXECUTION (– 1) EXCEPTION_CONTINUE_SEARCH (0) EXCEPTION_EXECUTE_HANDLER (1)
我们也可以通过一个函数来返回三个值。让 except 被触发时,作更精准的处理。而这个函数一般会调用 Windows的 两个错误代码处理的API函数: GetExceptionCode() : 返回错误代码; GetExceptionInformation() : 取得错误信息结构。
嵌入异常处理与自定义处理函数示例:
int ErrorFunc(unsigned int code, struct _EXCEPTION_POINTERS *ep)
{
puts("my Error infomathion.");
if (code == EXCEPTION_ACCESS_VIOLATION) {
puts("caught AV as expected.");
return EXCEPTION_EXECUTE_HANDLER; // =1 执行被调用的 except 处理过程
}
else {
puts("didn‘t catch AV, unexpected.");
return EXCEPTION_CONTINUE_SEARCH; // =0 继续让下一个 except处理
};
}
double myFunc(int a, int b)
{
double r;
//exit(0);
__try
{
r = a / b;
cout << "Cacle..." << endl;
}
__except (ErrorFunc(GetExceptionCode(), GetExceptionInformation()))
{
// 如果 ErrorFunc 返回值为 1 下面的语句才会执行
unsigned int code = GetExceptionCode();
cout << "ERROR!:" << code << endl;
//throw;
}
cout << "...end1..." << endl;
return r;
}
int _tmain(int argc, _TCHAR* argv[])
{
int v1, v2;
v1 = 1; v2 = 0;
double x=0;
__try
{
x = myFunc(v1, v2); // 调用函数,嵌入式 __try __except 示范。
cout << x << endl;
}
__except (1)
{
cout << "Error!" << endl;
}
cout << "...end2..." << endl;
system("pause");
return 0;
}
SEH异常处理模型中,异常通过RaiseException()函数抛出。RaiseException()函数的作用类似于C++异常模型中的throw。可以通过这个函数,主动处理预知的异常。
主动抛出异常示例:
int _tmain(int argc, _TCHAR* argv[])
{
int v1, v2;
v1 = 1; v2 = 0;
double x=0;
__try
{
// x = v1 / v2;
RaiseException(100, 0, 0, NULL); //主动抛出错误 100 是自己定义的异常代码
cout << x << endl;
}
__except (1)
{
UINT code = GetExceptionCode();
if (code==100) // 判断自己抛出的异常代码
cout << "Error! Code:"<< code << endl;
}
cout << "...end..." << endl;
system("pause");
return 0;
}
类型化的 C++异常
C++的异常处理很简单,就是三个关键字 try, throw, catch来完成。他在很多地方有关系性作用。但这里只作简单地了解。
try
{
//这里写入一些代码
int a=10, b=0;
int x;
if (b==0)
throw 1; // 抛出异常。终止以下的代码执行 。
if (a==1);
throw 2; // 再抛出个异常。终止以下的代码执行 。
x = a/b; // b=0. 会产生运算异常。
}
catch int i
{
if (i==1) // 由 throw 抛出的值 =1
cout << "b=0 is error!" <<endl;
if (i==2) // 由 throw 抛出的值 =2
cout << "i=1 is error!" <<endl;
}
catch(...){} //接受所有异常
如 果想用 try{} catch{}来捕捉一些意想不到的异常,是靠不住的。也就是说他需要在 try {} 中主动发现异常,然后通过 throw, 抛出异常,让 catch来处理。如果是你发现不了的异常,如果无法throw出来,也就无法处理。如上例中: if (b==0) throw 1; 这句不要。执行到 x=a/b; 是会产生一个系统错误。try{}catch{} 中不会主动识别这个异常。但 try , catch 的用法有很多。可以找更多的资料去了解下。我也未了解清楚。
以下内容容易不被了解:
catch 没有捕获到匹配的异常的时候,会调用默认的终止函数。可以调用 set_terminate()来设置终止函数,参数是一个函数指针,类型是:void (*terminate)(); 实际上是调用默认的unexpected()函数,而这个默认的unexpected() 调用了 set_terminate() 中设定的终止函数。可以用set_unexpected()来设置unexpected。
如下:( 但这一段代码在VC下编译执行不会发生什么!)
void myUnexpected() {
cerr << "unexpected called\n";
throw 0; // throws int (in exception-specification)
}
void myfunction() throw (int) {
throw ‘x‘; // throws char (not in exception-specification)
}
int _tmain(int argc, _TCHAR* argv[])
{
int v1, v2;
v1 = 1; v2 = 0;
double x=0;
set_unexpected(myUnexpected);
try
{
myfunction(); // x = v1 / v2;
}
catch (int) {
cerr << "caught int/n";
}
catch (...){
cerr << "caught other exception (non-compliant compiler?)\n";
};
}
VC 在Release方式下如果选择了编译器代码优化选项,则会去搜索try块中的代码, 如果没有找到throw代码, 就会认为try catch结构是多余的, 给优化掉。 这样造成在Release模式下。如果不在 try{}中主动throw抛出一个异常。在VC 的 Release编译模式下,try catch 是被忽略掉的。
本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标编程语言VC/MFC频道!
您输入的评论内容中包含违禁敏感词
我知道了
请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号