如何在C++中记录异常情况?

Dim*_* C. 4 c++ logging exception-handling exception

在编写函数时,我的实现经常看起来像这样:

  • 调用子功能
  • 如果此子功能无法执行(由于异常情况):记录此故障并中止当前功能
  • 否则继续调用其他子功能,这反过来可能会失败

关键部分是伐木.每个失败的函数都应该在日志中添加简短描述.这样,在处理异常的级别,可以向用户显示详细的错误消息.

例如,考虑一个可以创建新用户帐户的应用程序,并且数据库连接存在问题.以下反向堆栈跟踪结果:

  • SQLDriverConnect() - >"SQLDriverConnect错误:未找到数据源且未指定默认驱动程序"
  • OpenDatabaseConnection() - >"无法打开数据库连接"
  • CreateUser() - >"无法创建新用户"
  • ValidateAndSaveNewUserAccount() - >"无法保存用户配置文件"
  • 捕获异常并将记录的消息显示给用户

使用例外功能,我将按如下方式实现:

void CreateUser()
{
    try {
        OpenDatabaseConnection();
    }
    catch(std::exception& e) {
        e.AddLog("Failed to create the new user");
        throw;
    }
    //...
}
Run Code Online (Sandbox Code Playgroud)

使用简单的返回值,我写下以下内容:

bool CreateUser(Log& log)
{
    if (!OpenDatabaseConnection(log))
    {
        log.Add("Failed to create the new user");
        return false;
    }
    //...
    return true;
}
Run Code Online (Sandbox Code Playgroud)

我发现两种实现都同样好.因此,我没有看到使用异常的优势.我很清楚异常处理通常被认为是一个有用的功能,但我真的不明白为什么.很久以前,我广泛使用异常处理,但我没有看到它的大优势,所以现在我再也不用它了.因此我的问题:

  • 使用异常,如何更简洁地在C++中实现?
  • 如果不是,那么抛出异常而不是返回"成功"布尔值的优点是什么呢?

注意:我使用术语日志记录 "收集对错误的解释,以便稍后可以将其呈现给用户".我宁愿不将该解释存储在日志消息的全局集合中(在内存中,在文件中或在数据库中),因为它直接描述了特定的异常.

更新:感谢您的回复.我知道只有当用户不需要有关错误的详细反馈时,例外才有用.(如果我误解了这个,请纠正我.)

Ele*_*tal 6

您的策略似乎避免了异常的最有用方面,您可以抛出一个异常类,其中已经包含日志信息的文本 - 这是在异常被抛出时生成日志的文本而不是异常时被抓住了.然后你不必抓住每个级别上升到堆栈,但只在顶层.

因此,只有一个try块和一个log.add - 一般来说代码少得多.这样的东西似乎删除了所有的复制.

void OpenDatabaseConnection()
{
   if (Error) throw MyException("Failed opening database");
}

void CreateUser()
{
    try {
        OpenDatabaseConnection();
        //...... do everything here
    }
    catch(MyException& E) { //only one copy of this code
        E.AddLog(E.getMessage());
        throw;
    }
}
Run Code Online (Sandbox Code Playgroud)