运行时异常消息而不扩展 std::exception

Runtime exception messages without extending std::exception

本文关键字:std exception 扩展 异常 消息 运行时      更新时间:2023-10-16

我有一些这样的代码:

class ParseError: public exception {
protected:
  mutable string msg;
  int position;
public:
  explicit ParseError(const string& message, const int index) {
    msg = message;
    position = index;
  }
  virtual ~ParseError() throw () {
  }
  const char * what() const throw () {
    stringstream ss(msg);
    ss << "Parse error at position " << position << ": " << msg;
    msg = ss.str();
    return msg.c_str();
  }
};

当我扔掉它时,我在 valgrind 下运行单元测试时看到这样的东西:

foo.h:102:意外异常,并显示消息:"位置 9 处的解析错误:发现意外字符:等等"

这就是我想要的,但我很好奇exception基类在幕后做什么。如果我不扩展exception而是保持类的其余部分不变,我会得到这个:

foo.h:102:意外异常,消息:"未知异常"

我需要向我的类添加什么才能不扩展exception并且仍然显示消息?

顺便说一句,我意识到我可能应该扩展runtime_error而不是exception.在这种情况下,我很好奇是什么让exception幕后打勾,我不一定在寻找有关最佳实践的建议。

如果不

处理异常,则无法保证会收到有用的错误消息;唯一的保证是程序将通过调用std::terminate终止。

似乎您的实现能够识别未处理的异常派生自 std::exception ,并使用该知识调用其 what() 覆盖以生成错误消息。它对非标准异常类型一无所知,也不应该仅仅因为它们碰巧与完全不相关的类中的函数同名而随机调用函数。

如果要在抛出任意类型时打印有用的内容,则需要一个处理程序来捕获该类型并对其进行正确的操作。但我绝对建议你只抛出派生自std::exception的类型,除非你有很好的理由抛出其他东西。

这里有两个问题:

在此函数中,您将msg放在自身:

  const char * what() const throw () {
    stringstream ss(msg);
                 ** ^^^
    ss << "Parse error at position " << position << ": " << msg;
    **                                                      ^^^

但这并不重要,因为您的第二个问题是您应该将创建消息从 what() 移动到构造函数。 what()应该只返回它。

class ParseError: public exception {
protected:
  string msg;
public:
  explicit ParseError(const string& message, const int index) {
    ostringstream ss;
    ss << "Parse error at position " << position << ": " << message;
    msg << ss.str();
  }
  const char * what() const throw () {
    return msg.c_str();
  }
};