我不确定是否应该采用例外的方式。我经常想知道"我是否必须在此处捕获此信息,或者在调用堆栈中是否更高?"和那样的事情。但我已经创建了一个小的异常类,以获得某种类似C#的异常,它可以显示一堆异常:
class Exception : public std::exception
{
protected:
std::string _trace;
public:
Exception()
: _trace( "[ERROR - " + (std::string) DateTime() + "]"
{ }
Exception & push( const std::string & msg )
{
this->_trace += '\n\t' + msg;
return *this;
}
virtual const char * what() const
{
return this->_trace.c_str();
}
};
我可以这样使用:
function depth0()
{
try
{
depth1();
}
catch( Exception & exc )
{
throw exc.push( "depth0() - Failed." );
}
}
function depth1()
{
try
{
depth2();
}
catch( Exception & exc )
{
throw exc.push( "depth1() - Failed." );
}
}
function depth2()
{
try
{
depth3();
}
catch( Exception & exc )
{
throw exc.push( "depth2() - Failed." );
}
}
function depth3()
{
if( something goes wrong )
{
throw Exception().push( "depth3() - Failed." );
}
}
try
{
depth0();
}
catch( Exception & exc )
{
std::cout << exc.what() << std::endl;
}
我不必抓住并抛出每个深度的callstack,这只是一个例子。
这是使用例外的正确方法吗?它不反对例外哲学吗? (我还不明白)。
谢谢:)
PS:我使用的是Java和C#标签,因为这一般都是关于异常的,即使样本是用C ++编写的。
答案 0 :(得分:1)
作为一般规则:捕获可以处理它的异常。并在可能的情况下捕获特定的异常。就像连接到您的数据库一样 - 您永远不会想要向用户弹出异常 - 在最坏的情况下包含连接字符串详细信息。因此,您的业务逻辑层必须捕获数据库异常并尽可能地处理它(再次尝试连接,记录异常等)并抛出前端可以保存处理的一些异常(自定义数据库连接异常或其他没有详细说明) )。
另一方面,你无法处理好的事情(内存异常等)你可以在应用程序级别捕获并回复一些(自定义,但至少是通用的)信息给用户出错的地方。如果可能,使应用程序进入稳定状态。