为什么人们把虚拟关键字放在std :: exception :: what()之前?

时间:2012-11-06 19:24:14

标签: c++ inheritance virtual

我最近开始使用std::exception作为我所有异常的基类。如果不将what()关键字放在前面,我就无法正确覆盖virtual。如果没有virtual关键字,它似乎总是调用基类的what()函数std::exception

它让我感到困惑,因为我认为在覆盖它时(here is a post似乎证实了这一点),我永远不需要将virtual放在函数前面。但我决定让它继续前进。

然后今天在阅读O'Reilly的“安全C ++”时,我发现作者还用虚拟关键字覆盖了what()。他写道......

virtual const char* what() const throw () { /* stuff */ }

为什么他会覆盖某个功能并使用virtual关键字?它只是用于我在上面引用的帖子中建议的“文档”吗?

1 个答案:

答案 0 :(得分:3)

你做必须将virtual关键字放在what()的覆盖之前,以便调用子类实现。也许当您发现它正在调用基类实现时,您引用的异常对象已经通过异常的异常传递进行了切片?例如,我总是通过引用捕获(根据Scott Meyers的建议),但是如果我抓住异常值并将catch声明为可能抛出的子类的超类,那么当我捕获它时,对象将被切片。换句话说,如果我声明了这个异常子类:

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)
{
    ...
}