【问题标题】:Properly using exceptions正确使用异常
【发布时间】:2014-08-08 16:59:03
【问题描述】:

我不确定应该如何使用异常。我经常想知道“我必须在这里捕获这个,还是在调用堆栈中更高?”诸如此类的事情。但是我创建了一个小的异常类来拥有某种类似 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;
}

我不必在调用堆栈的每个深度都捕获和抛出,这只是一个示例。

这是使用异常的正确方法吗?这不是违反例外哲学吗? (我还不明白)。

谢谢你:)

PS : 我使用 Java 和 C# 标记,因为这通常是关于异常的,即使示例是在 C++ 中的。

【问题讨论】:

  • 你应该很少在 C++ 中尝试捕捉,而是围绕 RAII 习惯构建你的代码:en.m.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization
  • 谢谢。我读了你的文章,但我不明白与此的关系。
  • 不回答您的问题,但作为 C++ 的提示:您可以使用 throw;(无参数)重新抛出异常。这意味着您不会像在您的示例中那样抛出副本:exc.push(...); throw;
  • 阅读“好处”部分并尝试编写异常安全的 C++ 代码,该代码在使用 RAII 和不使用 RAII 的范围内分配内存
  • @Matthias247 它会抛出副本吗?它不会抛出参考吗? :o

标签: java c# c++ exception callstack


【解决方案1】:

作为一般规则:在可以处理的地方捕获异常。并在可能的情况下捕获特定异常。就像连接到您的数据库一样 - 您永远不会希望向用户弹出异常 - 在最坏的情况下包含连接字符串详细信息。因此,您的业务逻辑层必须捕获数据库异常并尽可能处理它(再次尝试连接、记录异常等)并抛出一些前端可以保存处理的异常(自定义数据库连接异常或其他不提供任何细节的异常) )。

另一方面,您无法很好地处理某些事情(内存不足异常等),您可以在应用程序级别捕获并用一些(如果可能的话自定义,但至少是通用的)信息向用户响应出现问题。如果可能,使应用程序进入稳定状态。

【讨论】:

  • 感谢您的回答。让我对异常不那么困惑了。
猜你喜欢
  • 2012-05-07
  • 1970-01-01
  • 1970-01-01
  • 2015-11-22
  • 2018-07-09
  • 2014-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多