我最近开始使用std::exception
作为基类。我无法在不将virtual
关键字放在其前面的情况下正确覆盖what()
。没有virtual
关键字,它似乎总是调用基类的what()
功能,std::exception
。
这让我有些困惑,因为我认为在覆盖它时,我不需要将virtual
放在功能前(这似乎是证实这一点的帖子)。但是我决定让它继续前进。
今天,在阅读O'Reilly的"安全C "时,我发现作者还用虚拟关键字覆盖what()
。他写了...
virtual const char* what() const throw () { /* stuff */ }
为什么他覆盖功能并使用virtual
关键字?它只是为了"文档",正如我上面引用的帖子中所建议的吗?
您做不是必须将虚拟关键字放在您的覆盖面前,以调用子类实现。也许当您发现它正在调用基类实现时,您所引用的异常对象是通过异常的不适当传递切成薄片的?例如,我总是通过参考(根据Scott Meyers的建议)来捕获,但是如果我被异常值抓住并宣布该捕获是可能被抛出的子类的超级类,那么当我抓住它时,该对象将被切成薄片。换句话说,如果我有此例外子类声明:
class my_exception : public std::exception
...
我抓到了一个实例:
try
{
...
throw my_exception("Some message");
}
catch (std::exception e)
{
...
}
e
在捕获块中是切成薄片的对象。您应该捕获这样的例外:
try
{
...
throw my_exception("Some message");
}
catch (std::exception& e)
{
...
}