我尝试了各种方法;这对我有用:
从子类化 runtime_error 开始:
/*----------------------------------------------------------------------*/
/* subclass runtime_error for safe exceptions in try/throw/catch */
#include <stdexcept>
/* a little preprocessor magic here -- makes a subclass of runtime_error*/
#define NEWERROR( NE ) class NE : public runtime_error { \
public: NE ( string const& error ) : runtime_error(error) {} }
NEWERROR( FileError );
NEWERROR( NetworkError );
NEWERROR( StringError );
NEWERROR( CofeeError );
/*----------------------------------------------------------------------*/
然后您可以创建一些异常实例。
/*----------------------------------------------------------------------*/
/* some example pre-defined exceptions */
FileError ReadOnly ( "ReadOnly" );
FileError FileNotFound ( "FileNotFound" );
NetworkError TimeOutExceeded ( "TimeOutExceeded" );
NetworkError HostNotFound ( "HostNotFound" );
CoffeeError OutOfCoffee ( "OutOfCoffee" );
/*----------------------------------------------------------------------*/
明确通知编译器你的函数可能会抛出异常
或者程序可能会在抛出点终止,并且数据可能会丢失或损坏
如果资源当时正在使用中。
“确保你能抓到任何你能扔的东西。”
(我使用通用的 runtime_error 因为抛出和捕获它涵盖了所有
我的例外加上系统的例外。)
/*----------------------------------------------------------------------*/
/* example function that may throw an exception */
#include <fstream>
ifstream& getFileStream (string fname) throw (runtime_error)
{
if ( fname == "" )
throw StringError( "<getFileStream> fname:empty string" );
// processing stops here if thrown
try
{
ifstream Inputfstream;
ifstream& ifsref = Inputfstream;
// ifstream has its own <legacy> exception
// mechanisms and procedures
ifsref.exceptions ( ifstream::failbit | ifstream::badbit );
ifsref.open (fname , ifstream::in); // could fail ==> ifstream::failure exception
}
catch (ifstream::failure e)
{
throw FileError( fname + string(e.what() ) );
}
return ifsref;
}
/*----------------------------------------------------------------------*/
然后在你的 try/catch 中
/*----------------------------------------------------------------------*/
catch (FileNotFound fnf) //catch a specific error
{
if (DEBUG) cerr << "[File Not Found Error: " << fnf.what() << "]" << endl;
... (handle it) ...
}
catch (FileError fe) //catch a specific type
{
if (DEBUG) cerr << "[File Error: " << fe.what() << "]" << endl;
... (handle it) ...
}
catch (runtime_error re ) // catch a generic type
{
if (DEBUG) cerr << "[Runtime error: " << re.what() << "]" << endl;
// determine type by string comparison
if ( re.what() == string("ResourceNotavailable") ) ...
if ( re.what() == string("NetWorkError") ) ...
...
}
catch ( ... ) // catch everything else
{ ... exit, rethrow, or ignore ... }
/*----------------------------------------------------------------------*/
runtime-error类在c++标准库中有很好的支持,
编译器在内部知道它,以及如何优化内存和调度,
因此您可以安全而自信地在不同的代码库中使用它们。该代码是可移植的并且与许多不同的编译器和架构兼容。
如果你觉得一系列字符串匹配是对 CPU 和内存的严重浪费(编译器会优化这些) .
<stdexcept> 在 2 组中为您提供了几种异常:
其中一些的用法语法略有不同。
C++ 中的传统智慧说您的异常应该相对“平坦”,
这意味着应该避免特定类别的异常的大层次结构
对于一般的编程任务,偏爱简短的通用但信息丰富的。网络系统逻辑、高等数学等特定领域的任务可能会受益于特异性,但这可以通过使用通用运行时/逻辑异常生成智能错误字符串来轻松实现。
最后,我的观点是:您可以通过以下方式实现所有这一切
仅抛出和捕获 runtime_error。
您不必创建一整套高度具体的异常
(就像 java 一样)对于每个类,每个类都处理一个特定的错误。