MFC异常处理的问题
参考文献:http://technet.microsoft.com/zh-cn/library/t078xe4f(v=vs.85).aspx
MFC中异常处理的语法和语义构建在标准C++异常处理语法和语义的基础之上,其解决方案为:MFC异常处理 = MFC 异常处理类 + 宏
1 宏:
MFC定义了TRY、CATCH(及AND_CATCH、END_CATCH)和THROW(及THROW_LAST)等用于异常处理的宏,其本质上也是标准C++的try、catch和throw的进一步强化,由这些宏的定义可知:
#ifndef _AFX_OLD_EXCEPTIONS
#define TRY { AFX_EXCEPTION_LINK _afxExceptionLink; try {
#define CATCH(class, e) } catch (class* e) \
{ ASSERT(e->IsKindOf(RUNTIME_CLASS(class))); \
_afxExceptionLink.m_pException = e;
#define AND_CATCH(class, e) } catch (class* e) \
{ ASSERT(e->IsKindOf(RUNTIME_CLASS(class))); \
_afxExceptionLink.m_pException = e;
#define END_CATCH } }
#define THROW(e) throw e
#define THROW_LAST() (AfxThrowLastCleanup(), throw)
// Advanced macros for smaller code
#define CATCH_ALL(e) } catch (CException* e) \
{ { ASSERT(e->IsKindOf(RUNTIME_CLASS(CException))); \
_afxExceptionLink.m_pException = e;
#define AND_CATCH_ALL(e) } catch (CException* e) \
{ { ASSERT(e->IsKindOf(RUNTIME_CLASS(CException))); \
_afxExceptionLink.m_pException = e;
#define END_CATCH_ALL } } }
#define END_TRY } catch (CException* e) \
{ ASSERT(e->IsKindOf(RUNTIME_CLASS(CException))); \
_afxExceptionLink.m_pException = e; } }
这些宏在使用语法上,有如下特点:
1)用TRY 块包含可能产生异常的代码;
(2)用CATCH块检测并处理异常。要注意的是,CATCH块捕获到的不是异常对象,而是指向异常对象的指针。此外,MFC靠动态类型来辨别异常对象;
(3)可以在一个TRY 块上捆绑多个异常处理捕获块,第一次捕获使用宏CATCH,以后的使用AND_CATCH,而END_CATCH则用来结束异常捕获队列;
(4)在异常处理程序内部,可以用THROW_LAST 再次抛出最近一次捕获的异常。
2 MFC 异常处理类
MFC较好地将异常封装到CException类及其派生类中,自成体系,下表给出了MFC 提供的预定义异常:
异常类 含义
CMemoryException 内存不足
CFileException 文件异常
CArchiveException 存档/序列化异常
CNotSupportedException 响应对不支持服务的请求
CResourceException Windows 资源分配异常
CDaoException 数据库异常(DAO 类)
CDBException 数据库异常(ODBC 类)
COleException OLE 异常
COleDispatchException 调度(自动化)异常
CUserException 用消息框警告用户然后引发一般 CException 的异常
标准C++的异常处理可以处理任意类型的异常,而MFC 宏则只能处理CException 的派生类型,下面我们看一个CFileException的使用例子:
CODE:
#include <iostream.h>
#include "afxwin.h"int main()
{
TRY
{
CFile f( "d:\\1.txt", CFile::modeWrite );
}
CATCH( CFileException, e )
{
if( e->m_cause == CFileException::fileNotFound )
cout << "ERROR: File not found\n" << endl;
}
END_CATCH
}
在这个程序中,如果D盘根目录下不存在"1.TXT"这个文件,将抛出CFileException异常,而且错误原因成员变量m_cause被设置为fileNotFound,我们以CATCH( CFileException, e )就可以捕获到。错误原因被定义为CFileException中的枚举(enum),如下:
CODE:
enum {
none,
generic,
fileNotFound,
badPath,
tooManyOpenFiles,
accessDenied,
invalidFile,
removeCurrentDir,
directoryFull,
badSeek,
hardIO,
sharingViolation,
lockViolation,
diskFull,
endOfFile
};
我们在使用MFC相关类时,MFC会自动抛出异常,当然我们也可以自行在程序中利用AfxThrowXXXException()抛出各种类型的异常,其中的XXX与前文的MFC异常类表对应。我们看AfxThrowFileException的例子:
CODE:
#include <iostream.h>
#include "afxwin.h"int main()
{
TRY
{
AfxThrowFileException(CFileException::fileNotFound);
}
CATCH( CFileException, e )
{
if( e->m_cause == CFileException::fileNotFound )
cout << "ERROR: File not found\n" << endl;
}
END_CATCH
}
在此程序中,我们在TRY块自行利用MFC提供的全局函数AfxThrowFileException抛出了CFileException异常,其后在CATCH块抓住了这个异常。
MFC建议不再使用TRY、CATCH和THROW宏,而是直接使用标准C++的方式。
MFC异常处理的问题的更多相关文章
- VS2010/MFC编程入门之四十六(MFC常用类:MFC异常处理)
上一节中鸡啄米讲了CFile文件操作类,本节主要来说说MFC异常处理. 在鸡啄米C++编程入门系列的最后一节鸡啄米:C++编程入门系列之五十(异常处理)中,鸡啄米讲了C++标准异常的处理机制,如果你还 ...
- VS2010-MFC(MFC常用类:MFC异常处理)
转自:http://www.jizhuomi.com/software/236.html 上一节讲了CFile文件操作类,本节主要来说说MFC异常处理. 在鸡啄米C++编程入门系列的最后一节鸡啄米:C ...
- VS2010/MFC编程入门教程之目录和总结
鸡啄米的这套VS2010/MFC编程入门教程到此就全部完成了,虽然有些内容还未涉及到,但帮助大家进行VS2010/MFC的入门学习业已足够.以此教程的知识为基础,学习VS2010/MFC较为深入的内容 ...
- MFC常用类
CString CStringT 操作可变长度字符串的模板类CStringT有三个实例:CString.CStringA和CStringW,它们分别提供对TCHAR.char和wchar_t字符类型的 ...
- MFC教程
MFC教程 还有VS2015的视频教程 试看教程地址:http://dwz.cn/4PcfPk免费下载地址:http://dwz.cn/mfc888 一.VS2010/MFC编程入门教程之目录 第一部 ...
- VS2010/MFC编程入门之四十七(字体和文本输出:CFont字体类)
上一节中鸡啄米讲了MFC异常处理,本节的主要内容是字体CFont类. 字体简介 GDI(Graphics Device Interface),图形设备接口,是Windows提供的一些函数和结构,用于在 ...
- (转)VS2010-MFC编程入门教程之目录和总结
目前该教程可以到鸡啄米编程课堂去学习,阅读体验更好,更适合在线学习. 原文目录及链接: 一.VS2010/MFC编程入门教程之目录 第一部分:VS2010/MFC开发环境 VS2010/MFC编程入 ...
- win32/mfc/qt 异常处理与总结
际异常一: libcpmtd.lib(xmbtowc.obj) : error LNK2001: unresolved external symbol __CrtDbgReport Debug/B机. ...
- VC++/MFC 最常用宏和指令
1.#include指令 包含指定的文件,最基本的最熟悉的指令,编程中不得不用,包含库文件用双尖括号,包含自定义头文件用双引号. 2.#define指令 预定义,通常用它来定义常量(包括无参量与 ...
随机推荐
- 【BZOJ】【2435】【NOI2011】道路修建
DFS/DP 本来以为是一道傻逼题,然而跪了好久……一直RE…… 直接dfs就好了……x->y val=c : ans+=abs(n-size[y]-size[y])*c; 然而为啥会一直R ...
- Oracle—RMAN完全恢复
一.RMAN完全恢复的相关概念 1.在RMAN完全恢复中主要使用两个命令,一个是restore,另一个是recover. 2.可以在三个级别恢复,数据库,表空间,数据文件. 3.RMAN中应对于各种情 ...
- iOS开发-多线程简介
多线程从概念上理解是指从软件或者硬件上实现多个线程并发执行的技术,简单点理解就是同一时间可以执行多个事情(比如说一边听歌一边码代码),听歌是一个线程,码代码是一个线程,如果是单核CPU的话,上面两个动 ...
- Java基础(十):封装
在面向对象程式设计方法中,封装(英语:Encapsulation)是指一种将抽象性函式接口的实现细节部份包装.隐藏起来的方法.封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访 ...
- JSON在php中的使用
从5.2版本开始,PHP原生提供json_encode()和json_decode()函数,前者用于编码,后者用于解码. json_encode() ...
- 【转】gcc选项
http://zodiac1111.github.io/blog/config-gcc-warning/
- Logistic Regression的几个变种
原文:http://blog.xlvector.net/2014-02/different-logistic-regression/ 最近几年广告系统成为很多公司的重要系统之一,定向广告技术是广告系统 ...
- 【PHP 】 伪静态 - 3. 伪静态的基本使用
原理图: 原先浏览器输入的网址会发送到apache服务器,然后apache会调用php模块来处理,最后找到你所想访问的页面; 如果在apahce, httpd.conf文件中开启rewrite机制,则 ...
- 【linux】重置fedora root密码
I forget root password on fedora,debian.fedora 17 fedora 18 fedora 19 fedora 20 fedora 21 fedora .de ...
- ArcEngine真正释放锁文件,彻底移除图层
ArcMap在加载图层时会自动生成一个lock格式的加锁文件,右击移除图层后,加锁文件也会自动删除.但AE开发中却不能正常删除,移除图层后加锁文件依然存在,这就导致在其他地方无法对该图层进行操作,只有 ...