【问题标题】:Inherit Exceptions in C++ [duplicate]在 C++ 中继承异常 [重复]
【发布时间】:2017-01-12 15:54:25
【问题描述】:

我刚刚创建了一个异常层次结构,并希望我的 catch 块显示派生异常的消息。 我有 5 个这样的例外:

class ImagetypeException : public TGAException {  
public:  
const char* what() const throw();  
};  


const char* ImagetypeException::what() const throw() {
    return "Der Bildtyp ist nicht \"RGB unkomprimiert\".";
}

它们都是从 TGAException 派生的,即从 std::exception 派生的。

class TGAException : public std::exception {
public:
    virtual const char* what() const throw();
};

const char* TGAException::what() const throw() {
    return "Beim Einlesen oder Verarbeiten der TGA-Datei ist ein unerwarteter Fehler aufgetreten!";
}

所以我显然想在我的代码中的某个时刻抛出这些,并认为这可能是一个好主意,以尽量减少我需要的捕获块的数量。

catch (TGAException e) {
        cout << e.what() << endl;
    }

如果我这样做,将打印的消息是来自 TGAException 的消息,但我希望它显示更具体的派生消息。 那么,我需要做什么才能让它按我想要的方式工作呢?

【问题讨论】:

  • 通过引用捕获,如catch (TGAException&amp; e)。当你按价值捕捉时,你slice it
  • 更好的是,通过 const 引用捕获,因为您不打算更改异常对象。 @IgorTandetnik 你应该把这个作为答案(或者我会,但我不是想偷代表)
  • 你正在做对象切片,直到你通过引用捕获。
  • 其实"Der Bildtyp ist nicht \"RGB unkomprimiert\"."好像和std::invalid_argument匹配,你确定需要自己的异常类吗?

标签: c++ exception


【解决方案1】:

当你这样抓到时:

catch (TGAException e) {
    cout << e.what() << endl;
}

编译器复制原始异常并将其分配给 e。它使用 TGAException 复制构造函数,因此在 catch 块中看到的异常不是 ImagetypeException,而是 TGAException。这种现象称为对象切片。

如果你这样抓住它:

catch (const TGAException & e) {
    cout << e.what() << endl;
}

不需要副本,它会按照您期望的方式工作。

作为一般准则:始终通过引用捕获异常,并且几乎总是通过 const 引用捕获它们。

【讨论】:

  • 谢谢!非常有帮助且快速的答案:) 但首先是一个菜鸟问题-_-'
  • 不。一个好问题。您会惊讶于有多少经验丰富的 C++ 程序员被对象切片绊倒(注意:当参数和返回值按值传递时,甚至在目标不是指针或引用时的赋值时,它可能发生在方法调用中。)
猜你喜欢
  • 1970-01-01
  • 2019-03-20
  • 2012-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多