C++11 带来的新特性 (3)—— 关键字noexcept

C++11 带来的新特性 (3)—— 关键字noexcept,第1张

C++11 带来的新特性 (3)—— 关键字noexcept 1 关键字noexcept

从C++11开始,我们能看到很多代码当中都有关键字noexcept。


比如下面就是std::initializer_list的默认构造函数,其中使用了noexcept。


      constexpr initializer_list() noexcept
: _M_array(0), _M_len(0) { }

该关键字告诉编译器,函数中不会发生异常,这有利于编译器对程序做更多的优化。




如果在运行时,noexecpt函数向外抛出了异常(如果函数内部捕捉了异常并完成处理,这种情况不算抛出异常),程序会直接终止,调用std::terminate()函数,该函数内部会调用std::abort()终止程序。


2 C++的异常处理

C++中的异常处理是在运行时而不是编译时检测的。


为了实现运行时检测,编译器创建额外的代码,然而这会妨碍程序优化。




在实践中,一般两种异常抛出方式是常用的:

  • 一个 *** 作或者函数可能会抛出一个异常;
  • 一个 *** 作或者函数不可能抛出任何异常。


后面这一种方式中在以往的C++版本中常用throw()表示,在C++ 11中已经被noexcept代替。


    void swap(Type& x, Type& y) throw()   //C++11之前
{
x.swap(y);
}
void swap(Type& x, Type& y) noexcept //C++11
{
x.swap(y);
}
3 有条件的noexcecpt

在第2节中单独使用noexcept,表示其所限定的swap函数绝对不发生异常。


然而,使用方式可以更加灵活,表明在一定条件下不发生异常。


    void swap(Type& x, Type& y) noexcept(noexcept(x.swap(y)))    //C++11
{
x.swap(y);
}

它表示,如果 *** 作x.swap(y)不发生异常,那么函数swap(Type& x, Type& y)一定不发生异常。


一个更好的示例是std::pair中的移动分配函数(move assignment),它表明,如果类型T1和T2的移动分配(move assign)过程中不发生异常,那么该移动构造函数就不会发生异常。


    pair& operator=(pair&& __p)
noexcept(__and_<is_nothrow_move_assignable<_T1>,
is_nothrow_move_assignable<_T2>>::value)
{
first = std::forward<first_type>(__p.first);
second = std::forward<second_type>(__p.second);
return *this;
}
4 什么时候该使用noexcept?

使用noexcept表明函数或 *** 作不会发生异常,会给编译器更大的优化空间。


然而,并不是加上noexcept就能提高效率,步子迈大了也容易扯着蛋。




以下情形鼓励使用noexcept:

  • 移动构造函数(move constructor)
  • 移动分配函数(move assignment)
  • 析构函数(destructor)。


    这里提一句,在新版本的编译器中,析构函数是默认加上关键字noexcept的。


    下面代码可以检测编译器是否给析构函数加上关键字noexcept。


    struct X
{
~X() { };
}; int main()
{
X x; // This will not fire even in GCC 4.7.2 if the destructor is
// explicitly marked as noexcept(true)
static_assert(noexcept(x.~X()), "Ouch!");
}
  • 叶子函数(Leaf Function)。


    叶子函数是指在函数内部不分配栈空间,也不调用其它函数,也不存储非易失性寄存器,也不处理异常。


最后强调一句,在不是以上情况或者没把握的情况下,不要轻易使用noexception。


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/586193.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-12
下一篇 2022-04-12

发表评论

登录后才能评论

评论列表(0条)

保存