我最近开始使用 std::exception
作为我所有异常的基类。如果不在其前面放置 virtual
关键字,我无法正确覆盖 what()
。如果没有 virtual
关键字,它似乎总是调用基类 std::exception
的 what()
函数。
这让我有点困惑,因为我认为在覆盖函数时永远不需要将 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 block 中的 e
将是一个切片对象。你应该捕获这样的异常:
try
{
...
throw my_exception("Some message");
}
catch (std::exception& e)
{
...
}
关于c++ - 为什么人们将 virtual 关键字放在 std::exception::what() 前面?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13257932/