我最近开始使用 std::exception
作为所有异常的基类。如果不将 what()
关键字放在前面,我就无法正确覆盖 virtual
。如果没有 virtual
关键字,它似乎总是调用基类 what()
的 std::exception
函数。
这让我有点困惑,因为我认为在覆盖函数时永远不需要将 virtual
放在函数前面(而 here is a post 似乎证实了这一点)。但我决定放手继续前进。
然后今天在阅读 O'Reilly 的“Safe C++”时,我发现作者还用 virtual 关键字覆盖了 what()
。他写了...
virtual const char* what() const throw () { /* stuff */ }
为什么他要覆盖一个函数并使用
virtual
关键字?正如我上面引用的帖子中所建议的那样,它只是用于“文档”吗? 最佳答案
你做 而不是 必须将 virtual 关键字放在你覆盖 what() 的前面才能调用子类实现。也许当您发现它正在调用基类实现时,您引用的异常对象已通过异常的不适当传递被切片?例如,我总是通过引用捕获(根据 Scott Meyers 的建议),但是如果我通过异常值捕获并将捕获声明为可能抛出的子类的父类(super class),那么当我捕获它时,对象将被切片。换句话说,如果我声明了这个异常子类:
class my_exception : public std::exception
...
我捕获了一个这样的例子:
try
{
...
throw my_exception("Some message");
}
catch (std::exception e)
{
...
}
catch 块中的
e
将是一个切片对象。您应该捕获这样的异常:try
{
...
throw my_exception("Some message");
}
catch (std::exception& e)
{
...
}
关于c++ - 为什么人们把 virtual 关键字放在 std::exception::what() 前面?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13257932/