Alc*_*ott 5 c++ exception-specification
我有两个关于非投掷功能的问题:
为什么要使一个函数不抛?
如何使功能不抛?如果函数内部的代码实际可能throw,那么我还应该让它不抛?
这是一个例子:
void swap(Type t1, Type t2) throw()
{
//swap
}
Run Code Online (Sandbox Code Playgroud)
如果代码中swap根本不会抛出,我还应该追加throw()吗?为什么?
throw()(或noexcept在 C++11 中)之所以有用,有两个原因:
非抛出函数对于编写异常安全代码非常重要。例如,编写异常安全的通常方法operator=是通过非抛出swap()函数。
另一方面,其他异常规范是无用的,在当前标准中已被合理弃用。它们根本不能与模板很好地混合,而且执行起来成本太高。
现在,如果您noexcept在可能实际抛出的函数中使用规范,则所有赌注都将取消。即使您的编译器在异常离开函数时不终止程序(例如,VS 出于运行时效率的原因不会这样做),您的代码也可能由于优化而无法执行您的想法。例如:
void f() noexcept
{
a();
b();
}
Run Code Online (Sandbox Code Playgroud)
如果a()实际抛出并b()有副作用,函数行为将是不可预测的,因为您的编译器可能决定在b()之前执行a(),因为您已经告诉它不会抛出任何异常。
编辑:现在是问题的第二部分:如何使函数不抛出?
首先你需要问自己你的函数是否真的应该是非抛出的。例如:
class C
{
C* CreateInstance()
{
return new C();
}
}
Run Code Online (Sandbox Code Playgroud)
由于运算符new可以抛出std::bad_alloc,因此CreateInstance()可以抛出。您可以尝试使用 try-catch 块来避免它,处理或吞下可能在try块内抛出的任何异常,但这真的明智吗?例如:
C* CreateInstance()
{
try
{
return new C();
}
catch (...)
{
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
问题似乎解决了,但是您的来电者会准备好CreateInstance()返回null吗?否则,当他们尝试使用该指针时会发生崩溃。此外, astd::bad_alloc通常意味着您的内存不足,您只会推迟问题。
所以要小心:有些函数可以设置为非抛出,但其他函数应该被允许抛出。异常安全不是一件小事。
| 归档时间: |
|
| 查看次数: |
1618 次 |
| 最近记录: |