【问题标题】:Why do folks put the virtual keyword in front of std::exception::what()?为什么人们把 virtual 关键字放在 std::exception::what() 前面?
【发布时间】:2012-11-06 19:24:14
【问题描述】:

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

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

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

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

他为什么要覆盖一个函数并使用virtual 关键字?只是我在上面引用的帖子中建议的“文档”吗?

【问题讨论】:

  • override 会是更好的文档,因为如果您输入错误的签名会导致编译器错误,但是是的,afaik,很明显您正在覆盖它。
  • 确实,在覆盖时您并不严格需要 virtual 关键字。没有任何代码,我猜您的问题源于object slicing - 即您按值捕获异常:˙catch (std::exception e)
  • @chris:override 是一个 Microsoft 特定的扩展,尽管如果它在非 Microsoft 编译器中是 #defined,则它仍然可以用作文档。
  • @Chris:谢谢,所以我假设当我覆盖what() 时我并不真的需要使用virtual,而我的问题实际上是意外解决的其他问题。
  • @AdamRosenfield,它是 C++11 的一部分。 const char *what() const override {}throw 在 C++11 中已弃用,但我忘记了使用什么。也许noexcept 什么的。

标签: c++ inheritance virtual


【解决方案1】:

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

class my_exception : public std::exception
...

我像这样抓到了它的一个实例:

try
{
    ...
    throw my_exception("Some message");
}
catch (std::exception e)
{
    ...
}

e 在 catch 块中将是一个切片对象。您应该捕获这样的异常:

try
{
    ...
    throw my_exception("Some message");
}
catch (std::exception& e)
{
    ...
}

【讨论】:

  • 或者更确切地说:const std::exception&。但是否则当然是正确的答案,而且很可能是他错误的原因。不过,它是 "slicing" 而不是 "splicing",因为您将对象切成其子部分。
  • 很公平,但我不确定 const 是否真的在此处添加了任何内容,也没有提到 Scott Meyers 关于通过引用捕获异常的观点。抛出的异常不像函数/方法参数,因此通过 const 捕获不会添加任何内容(即编译器不会阻止您抛出异常,因为捕获不是 const)。
  • 您是否非常想念它?不!它会造成任何伤害吗?不!它是否使捕获异常而不修改它的意图(这会很奇怪)更清晰?大概!事实上,当我看到作为非常量引用传入的某些内容(无论是函数调用还是其他)时,我想知道是否要更改参数以及为什么要更改。当然你是对的,非常量引用在这里可能不会造成太大伤害,但是,当你可以使用 const 引用时,为什么还要使用非常量引用呢?
猜你喜欢
  • 2015-04-17
  • 1970-01-01
  • 2020-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-07
  • 2013-03-23
  • 2014-03-14
相关资源
最近更新 更多