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

时间:2012-10-01 02:38:33

标签: c++ exception

我有一些像这样的代码:

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位解析错误:找到意外字符:blah'

这就是我想要的,但我很好奇exception基类在幕后做了什么。如果我不扩展exception但是按原样离开课程的其余部分,我会得到这个:

  

foo.h:102:带有消息的意外异常:'未知异常'

为了能够不展开exception并且仍然显示消息,我需要向课程添加什么?

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

2 个答案:

答案 0 :(得分:2)

如果您不处理异常,则无法保证您会收到有用的错误消息;唯一的保证是通过致电std::terminate来终止该计划。

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

如果要在抛出任意类型时打印有用的东西,则需要一个处理程序来捕获该类型并使用它执行正确的操作。但我肯定会建议你只抛出从std::exception派生的类型,除非你有充分的理由抛出别的东西。

答案 1 :(得分:1)

这里有两个问题:

在此功能中,您将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();
  }

};