gpt4 book ai didi

c++ - 对非抛出函数的困惑

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:25:52 24 4
gpt4 key购买 nike

我有两个关于非抛出函数的问题:

  1. 为什么要使函数不抛出?

  2. 如何使函数不抛出?如果函数内的代码实际上可能会抛出,那么我是否仍应将其设置为非抛出?

这是一个例子:

void swap(Type t1, Type t2) throw()
{
//swap
}

如果 swap 中的代码根本不会抛出,我还应该附加 throw() 吗?为什么?

最佳答案

throw()(或 C++11 中的 noexcept)之所以有用,有两个原因:

  1. 它允许编译器更积极地进行优化。
  2. 它告诉函数使用者他们可以在他们自己的非抛出函数中使用这个函数。

非抛出函数对于编写异常安全代码非常重要。例如,编写异常安全 operator= 的常用方法是通过非抛出 swap() 函数。

另一方面,其他异常规范毫无用处,在当前标准中已被合理弃用。它们根本无法与模板很好地融合,而且执行起来成本太高。

现在,如果您在可能实际抛出异常的函数中使用 noexcept 规范,那么一切都将失败。即使您的编译器在异常离开函数时没有终止程序(例如,出于运行时效率原因,VS 不会这样做),您的代码也可能不会因为优化而按照您的想法进行。例如:

void f() noexcept
{
a();
b();
}

如果 a() 实际上抛出并且 b() 有副作用,函数行为将不可预测,因为你的编译器可能决定执行 b( )a() 之前,因为您已经告诉它不会抛出任何异常。

编辑:现在是问题的第二部分:如何使函数不抛出?

首先你需要问问自己你的函数是否真的应该是非抛出的。例如:

class C
{
C* CreateInstance()
{
return new C();
}
}

因为运算符 new 可以抛出一个 std::bad_alloc,所以 CreateInstance() 可以抛出。您可以尝试使用 try-catch block 来避免它,处理或吞没可能在 try block 内抛出的任何异常,但这真的明智吗?例如:

C* CreateInstance()
{
try
{
return new C();
}
catch (...)
{
return null;
}
}

问题似乎解决了,但是您的调用者是否准备好 CreateInstance() 返回 null?否则,当他们尝试使用该指针时就会发生崩溃。此外,std::bad_alloc 通常意味着您已用完内存,而您只是在推迟问题。

所以要小心:有些函数可以设为非抛出,但其他函数应该允许抛出。异常安全不是小事。

关于c++ - 对非抛出函数的困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11841963/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com