【问题标题】:what does this declaration mean? exception() throw()这个声明是什么意思?异常()抛出()
【发布时间】:2011-01-04 18:21:02
【问题描述】:

std::exception 类定义如下

exception() throw() { }
virtual ~exception() throw();
virtual const char* what() const throw();

声明中的 throw() 语法是什么意思? throw() 可以带参数吗?没有参数是什么意思?

【问题讨论】:

    标签: c++ stl


    【解决方案1】:

    不带任何参数,表示上述函数不会抛出任何异常。

    如果您指定任何参数作为参数,您的意思是该函数将只抛出该类型的异常。但是请注意,这不是对编译器的强制执行。如果碰巧抛出了某种其他类型的异常,程序将调用 std::terminate()。

    【讨论】:

    • 请注意,并非所有编译器都支持这种语法。特别值得注意的是,VS2008 没有。
    • 这是默认的意外异常处理程序。用户可以决定使用 std::set_unexpected() 来改变它。但是,这通常不会购买太多用户。 Herb Sutter 关于这个主题有一篇很棒的 GoTW 文章:gotw.ca/gotw/082.htm
    • @Neil:我相信 VC++ 能够识别异常规范,但它不会强制执行它们,除非最近发生了变化。
    • 在 VS 2008 中使用此类规范时,它的 IntelliSense 对我来说停止了该特定功能的工作:(
    • @Neil:VC++ 支持语法,但不强制语义。但是,它确实可以识别空异常规范,并根据它们的存在执行一些优化。任何抛出异常的空异常规范基本上都会导致未定义的行为。
    【解决方案2】:

    throw() 可以带参数吗?

    是的,它可用于声明该方法允许抛出的参数。

    此外,析构函数被标记为 throw(),析构函数永远不应该抛出异常,因为它们可能已经在抛出异常的上下文中执行。

    【讨论】:

    • 澄清一下,声明的析构函数是正确的: throw() 表示析构函数不会抛出异常,这是适当的模式。
    【解决方案3】:

    这称为抛出规范。它定义了可以从函数中抛出哪些异常(如果有)。

    这些在理论上听起来很棒,但使用它们存在问题。

    可以在SO question 找到关于此的很好的讨论。

    【讨论】:

      【解决方案4】:

      这是一个“异常规范”。 throw() 表示“这个函数不会抛出任何异常”。你也可以指定异常,所以 throw(foo) 会说这个函数可能会抛出 foo 类型的异常。

      这个特性的有用性在 C++ 社区中已经引起了相当多的争论——普遍的评价似乎是它不是特别有用。更多详情请查看this Herb Sutter article

      【讨论】:

      • 感谢该文章的链接。
      • 我有点反对所谓的“这个函数不会抛出任何异常”的意思。它的真正含义更像是“对该函数的调用将捕获它抛出的任何异常并终止”。如果人们这么想,赫伯萨特就不会说服他们这不是很有用。他们尤其不会认为空投规范是一种优化。
      • @Steve 好吧,大多数人真的 不想调用 terminate(),所以我认为他们努力让它像我所说的那样有意义。至于优化,我以前从未遇到过这种想法。
      • @Neil:是的,一些编译器(特别是 VC++,否则会忽略它们)基于空异常规范的存在进行优化。我还没有遇到任何可以很好地使用非空规范的人,但是空规范可能会有一些用处——特别是,如果没有至少一些保证不会导致结果的原语,大多数异常安全是不可能的在任何例外情况下(例如,通过复制和交换实现分配要求交换永远不会抛出)。
      • @Jerry:nothrow 函数很有用,但是用空抛出规范装饰它们就没有那么有用了。 IIRC,VC++ 优化实际上是错误的。它做了人们认为空抛出规范应该做的事情(假设函数不会抛出),而不是它实际意味着的事情(用 try/catch/terminate 包围调用)。
      【解决方案5】:

      这是一个exception specification。没有参数意味着函数不能抛出任何异常。

      【讨论】:

        猜你喜欢
        • 2014-09-20
        • 2022-12-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-07-20
        相关资源
        最近更新 更多