【问题标题】:C++ custom exception message not displayingC++ 自定义异常消息不显示
【发布时间】:2017-07-09 06:44:40
【问题描述】:

我正在尝试创建一个自定义异常类,将其抛出并显示错误消息,但我做错了什么,导致异常没有被抛出并且消息没有被打印出来。

这是异常类:

class UnbalancedParenthesesException : public std::exception {
  int line_number {0};
public:
  UnbalancedParenthesesException(int line_number) :
    line_number { line_number }
    {}

  virtual const char* what() const throw() {
    std::string exception_message =
      "Papentheses imbalance at line " + std::to_string(line_number) + "\n";

    return exception_message.c_str();
  }
};

我正在尝试try/throw/catch如下:

void handle_closed_paren(int line_number) {
  try { 
    if (definitely_unbalanced()) {
      throw UnbalancedParenthesesException(line_number);
    }
  } catch (const UnbalancedParenthesesException& e) {
      std::out << e.what() << "\n";
}

控制台中没有与此错误相关的内容。

提前致谢。

【问题讨论】:

  • return exception_message.c_str(); 返回将在返回时销毁的本地堆栈变量的地址。
  • @RichardCritten:答案在下面谢谢
  • 谢谢,理查德。这确实是问题所在。

标签: c++ c++11 exception-handling


【解决方案1】:

您的what() 方法正在创建一个本地std::string 变量,然后返回一个指向其内部数据的指针,当std::string 超出范围时该指针将悬空,并在what() 退出时销毁。

您需要将错误消息存储在作为该类成员的std::string 中,这样它就不会过早地超出范围。幸运的是,std::exception 已经为此目的有一个内部std::string。因此,与其在what() 本身中格式化错误消息,不如在派生构造函数中对其进行格式化并将其传递给基类构造函数,让what() 基方法按原样返回:

class UnbalancedParenthesesException : public std::exception
{
    int mLineNumber;
public:
    UnbalancedParenthesesException(int line_number) : std::exception("Parentheses imbalance at line " + std::to_string(line_number)), mLineNumber(line_number) {}

    // optional, if the catcher needs access to the value
    int lineNumber() const { return mLineNumber; }
};

【讨论】:

  • 谢谢,我喜欢这个解决方案。我不知道我可以像你在这里做的那样建造。
【解决方案2】:

当您在超出范围的std::string 上返回c_str() 的结果时,您的程序具有未定义的行为。任何事情都有可能发生。

除此之外,如果您没有看到异常,则说明没有抛出异常,可能是因为 definitely_unbalanced() 的结果是错误的。

使用调试器单步执行您的程序。

【讨论】:

  • 谢谢,这就是问题所在。我应该返回 char*,而不是本地 string
  • @progfan:嗯,不,这听起来不像是修复。谁创造了它所指向的东西?谁来破坏它?我建议将std::string 保留为异常对象的成员(在构造函数中构建它),然后您可以安全地返回它的c_str()
  • 你是对的。这样就变得乱七八糟了。我将在构造函数中构建string
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-18
  • 2010-09-27
  • 2015-11-04
相关资源
最近更新 更多