【问题标题】:Should I use noexcept for getters always?我应该总是使用 noexcept 作为吸气剂吗?
【发布时间】:2014-01-24 10:54:42
【问题描述】:

我应该在 C++11 中始终对 getter 使用 noexcept 方法修饰符吗?

我的意思是简单的 getter,只返回成员。 至少在我所有的吸气剂中,我这里不可能有一个例外 被抛出。一个缺点是 getter 过于冗长:

const std::string& getName() const noexcept{ return name; }

Stroustrup 书中指出的好处是编译器 可能会在这里和那里做一些优化。

【问题讨论】:

  • 这与通常的“我应该编写(琐碎的)getter 和 setter 吗?”非常相关。问题。如果你的 getter 真的那么简单,你可以保证它会保持noexcept,那么你真的需要它吗?
  • @juanchopanza 这是另一个很好的论点,是的。你建议我有公共成员?
  • 一般来说,这些琐碎的getter/setter是内联的,所以编译器可以很容易地推断出它们是noexcept
  • 目前我的看法是只值得添加 swap 和特殊成员函数。
  • @bames53 & juanchopanza:老问题,但我会质疑这个说法。琐碎的 getter 和 setter 可能是一个问题的迹象,但单独的琐碎的 getter 很自然地发生了。例如。想想isOpen()size()operator[]getID 之类的事情,一般来说,如果你想保护对象中的数据成员不被修改,那会破坏某些不变量,但仍然需要对它们进行读取访问。

标签: c++ c++11


【解决方案1】:

noexcept 是一个很难收回的承诺。例如,您可以稍后执行一些简单的操作,例如将返回类型更改为 std::string(无论出于何种原因),但是因为这需要分配字符串的副本,所以它可能会抛出异常。

因此标准采用了“仅在必要或非常有益时添加noexcept”的方式,我认为这是一个很好的规则。你需要问自己的问题是,这个方法的调用者是否需要它不抛出?

【讨论】:

  • 我不确定。这消除了静态分析器验证此方法确实不会抛出的能力。而且我不认为内存不足是一个好主意,这是java不包括这个的一个很好的理由。
  • Java 有一个OutOfMemoryError
  • 但是和 assert 一样,throw 子句不会跟踪它。
  • 说以后很难删除 noexcept 是真的,因为它是公共 API 的一部分,如果不破坏客户端代码就很难更改。这使得使用一个更改上述 API anyway 的返回类型的示例变得非常奇怪......如果你已经能够做到这一点,为什么还很难删除 noexcept同时?所有的赌注都已经结束了。
  • 它是 C++。几乎任何更改都需要重新编译。而且我们不是在谈论添加 noexcept,而是删除它,问题在于它可能会默默地破坏假设并导致 UB 或只是不正确的逻辑而编译器没有注意到。
【解决方案2】:

如果有人很可能需要这个 noexcept 限定符,我会添加它。如果你不添加它,你就有更多的可能性来改变实现(记住,这是 setter/getter 的常用参数 [而且我不是 setter 和 getter 的粉丝])。

如果你需要在“回滚,从错误中恢复”的情况下调用这个函数,你通常需要这个“不抛出”保证。例如,如果您想从析构函数中调用它,那么如果它提供 nothrow 保证(并且 noexcept 是提供该保证的现代方式),您的生活会更轻松。

所以,我不会制定一般规则来添加它。

【讨论】:

  • "回滚,从错误中恢复" - 例如,如果你想从析构函数中调用它,那么如果它提供 nothrow 保证,你的生活会更轻松(noexcept 是提供的现代方式那个)。
  • 谢谢,我已经添加了。 :-)
  • @SteveJessop noexcept 本身不提供任何保证,它只允许在发生异常时直接终止。
  • @TemplateRex:终止正是保证异常不会将函数转义到调用者的原因。确实,对noexcept 函数的调用会导致终止,但保证即使函数实现抛出异常也不会导致异常。我想你是否真的在提供 nothrow 保证的函数上标记noexcept 取决于noexcept 是否会给你的编译器带来性能成本——如果确实如此,并且你确定你的代码,那么你可能会选择省略它.但你希望它不会。
猜你喜欢
  • 1970-01-01
  • 2019-09-27
  • 1970-01-01
  • 2019-11-26
  • 2011-06-11
  • 2023-02-02
  • 1970-01-01
  • 2018-11-16
  • 1970-01-01
相关资源
最近更新 更多