CException
类
Microsoft 基础类库中所有异常的基类。
语法
class AFX_NOVTABLE CException : public CObject
成员
公共构造函数
名称 | 描述 |
---|---|
CException::CException |
构造 CException 对象。 |
公共方法
名称 | 描述 |
---|---|
CException::Delete |
删除 CException 对象。 |
CException::ReportError |
向用户报告消息框中的错误消息。 |
备注
因为 CException
是抽象基类,因此无法直接创建 CException
对象;必须创建派生类的对象。 如果需要创建自己的 CException
样式类,请使用上面列出的派生类之一作为模型。 确保派生类也使用 IMPLEMENT_DYNAMIC
。
派生类及其说明如下:
名称 | 描述 |
---|---|
CSimpleException |
资源关键型 MFC 异常的基类 |
CInvalidArgException |
参数异常条件无效 |
CMemoryException |
内存不足异常 |
CNotSupportedException |
请求不受支持的操作 |
CArchiveException |
特定于存档的异常 |
CFileException |
特定于文件的异常 |
CResourceException |
找不到或无法创建 Windows 资源 |
COleException |
OLE 异常 |
CDBException |
数据库异常(即基于开放式数据库连接的 MFC 数据库类出现的异常条件) |
COleDispatchException |
OLE 调度(自动化)异常 |
CUserException |
指示找不到资源的异常 |
CDaoException |
数据访问对象异常(即 DAO 类出现的异常条件) |
CInternetException |
Internet 异常(即 Internet 类出现的异常条件)。 |
这些异常旨在与 THROW
、THROW_LAST
、try
、catch
、and_catch
和 end_catch
宏配合使用。 有关异常的详细信息,请参阅异常处理,或参阅异常处理 (MFC) 一文。
若要捕获特定异常,请使用相应的派生类。 若要捕获所有类型的异常,请使用 CException
,然后使用 CObject::IsKindOf
来区分 CException
派生类。 请注意,CObject::IsKindOf
仅适用于使用 IMPLEMENT_DYNAMIC
宏声明的类,但可充分利用动态类型检查。 你创建的任何 CException
派生类也应使用 IMPLEMENT_DYNAMIC
宏。
可以通过调用 GetErrorMessage
或 ReportError
(两个成员函数,适用于 CException
的任何派生类)向用户报告有关异常的详细信息。
如果宏之一捕获了异常,系统会自动删除 CException
对象;你不要自行删除它。 如果使用 catch
关键字捕获异常,系统不会自动删除该异常。 若要详细了解何时删除异常对象,请参阅异常处理 (MFC) 一文。
继承层次结构
CException
要求
标头:afx.h
CException::CException
此成员函数构造一个 CException
对象。
explicit CException(BOOL bAutoDelete);
参数
b_AutoDelete
如果已在堆上分配 CException
对象的内存,则指定 TRUE
。 这将导致在调用 Delete
成员函数来删除异常时删除 CException
对象。 如果 CException
对象位于堆栈上或者是全局对象,则指定 FALSE
。 这种情况下,在调用 Delete
成员函数时,不会删除 CException
对象。
备注
通常不需要直接调用此构造函数。 引发异常的函数应创建 CException
派生类的实例并调用其构造函数,或者应使用 MFC 引发函数之一(例如 AfxThrowFileException
)来引发预定义类型。 提供本文档只是为了补全。
CException::Delete
此函数查看是否已在堆上创建了 CException
对象,如果答案为是,它会调用对象上的 delete
运算符。
void Delete();
备注
删除 CException
对象时,请使用 Delete
成员函数删除异常。 不要直接使用 delete
运算符,因为 CException
对象可能是全局对象或者已在堆栈上创建。
可以指定是否应在构造对象时删除对象。 有关详细信息,请参阅 CException::CException
。
只有在使用 C++ try
- catch
机制时,才需调用 Delete
。 如果使用的是 MFC 宏 TRY
和 CATCH
,则这些宏会自动调用此函数。
示例
CFile* pFile = NULL;
// Constructing a CFile object with this override may throw
// a CFile exception, and won't throw any other exceptions.
// Calling CString::Format() may throw a CMemoryException,
// so we have a catch block for such exceptions, too. Any
// other exception types this function throws will be
// routed to the calling function.
// Note that this example performs the same actions as the
// example for CATCH, but uses C++ try/catch syntax instead
// of using the MFC TRY/CATCH macros. This sample must use
// CException::Delete() to delete the exception objects
// before closing the catch block, while the CATCH example
// implicitly performs the deletion via the macros.
try
{
pFile = new CFile(_T("C:\\WINDOWS\\SYSTEM.INI"),
CFile::modeRead | CFile::shareDenyNone);
ULONGLONG ullLength = pFile->GetLength();
CString str;
str.Format(_T("Your SYSTEM.INI file is %u bytes long."), ullLength);
AfxMessageBox(str);
}
catch(CFileException* pEx)
{
// Simply show an error message to the user.
pEx->ReportError();
pEx->Delete();
}
catch(CMemoryException* pEx)
{
// We can't recover from this memory exception, so we'll
// just terminate the app without any cleanup. Normally, an
// an application should do everything it possibly can to
// clean up properly and _not_ call AfxAbort().
pEx->Delete();
AfxAbort();
}
// If an exception occurs in the CFile constructor,
// the language will free the memory allocated by new
// and will not complete the assignment to pFile.
// Thus, our clean-up code needs to test for NULL.
if (pFile != NULL)
{
pFile->Close();
delete pFile;
}
CException::ReportError
调用此成员函数,以向用户报告消息框中的错误文本。
virtual int ReportError(
UINT nType = MB_OK,
UINT nMessageID = 0);
参数
nType
指定消息框的样式。 将消息框样式的任意组合应用到框。 如果未指定此参数,则默认值为 MB_OK
。
nMessageID
指定在异常对象没有错误消息时要显示的消息的资源 ID(字符串表条目)。 如果为 0,则显示“没有错误消息”消息。
返回值
AfxMessageBox
值;否则为 0(如果没有足够的内存来显示消息框)。 请参阅 AfxMessageBox
,了解可能的返回值。
示例
以下是使用 CException::ReportError
的示例。 如需另一个示例,请参阅 CATCH
的示例。
CFile fileInput;
CFileException ex;
// try to open a file for reading.
// The file will certainly not
// exist because there are too many explicit
// directories in the name.
// if the call to Open() fails, ex will be
// initialized with exception
// information. the call to ex.ReportError() will
// display an appropriate
// error message to the user, such as
// "\Too\Many\Bad\Dirs.DAT contains an
// invalid path." The error message text will be
// appropriate for the
// file name and error condition.
if (!fileInput.Open(_T("\\Too\\Many\\Bad\\Dirs.DAT"), CFile::modeRead, &ex))
{
ex.ReportError();
}
else
{
// the file was opened, so do whatever work
// with fileInput we were planning...
fileInput.Close();
}