c++11中的noexcept关键字

 更新时间:2022年07月20日 10:33:52   作者:却道天凉_好个秋  
这篇文章主要介绍了c++11中的noexcept关键字,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

c++11中noexcept关键字

1. 概念

noexcept关键字是c++11之后新增的。该关键字会告诉编译器,被修饰的函数不会发生异常,这有利于编译器对程序做更多的优化。

2. 两种形式

1)noexcept

2)noexcept(expression)

noexcept(true) 表示被修饰的函数不抛出异常,noexcept(false) 表示被修饰的函数会抛出异常。

3. 异常处理

//例1
bool Compare(int x, int y) throw()   //C++11之前
{
    return x > y;
}
 
//例2
bool Compare(int x, int y) noexcept(noexcept(x > y))  //C++11
{
    return x > y;
}

例2用到了noexcept运算符,表示,如果x > y不发生异常,则Compare函数不会发生异常。

4. 实现原理

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

5. 使用场景

1)移动构造函数

2)移动分配函数

3)析构函数

4)叶子函数

c++11关键字noexcept替代throw

相比于断言适用于排除逻辑上不可能存在的状态,异常通常是用于逻辑上可能发生的错误。

在异常处理的代码中,程序员有可能看到过如下的异常声明表达形式:

void excpt_func() throw(int, double) { ... }

在excpt_func函数声明之后,我们定义了一个动态异常声明throw(int, double),该声明指出了excpt_func可能抛出的异常的类型。事实上,该特性很少被使用,因此在C++11中被弃用了(参见附录B),而表示函数不会抛出异常的动态异常声明throw()也被新的noexcept异常声明所取代。

noexcept形如其名地,表示其修饰的函数不会抛出异常。不过与throw()动态异常声明不同的是,在C++11中如果noexcept修饰的函数抛出了异常,编译器可以选择直接调用std::terminate()函数来终止程序的运行,这比基于异常机制的throw()在效率上会高一些。这是因为异常机制会带来一些额外开销,比如函数抛出异常,会导致函数栈被依次地展开(unwind),并依帧调用在本帧中已构造的自动变量的析构函数等。

noexcept修饰符有两种形式

  • 一种就是简单地在函数声明后加上noexcept关键字。比如:void excpt_func() noexcept; 
  • 另外一种则可以接受一个常量表达式作为参数,如下所示:void excpt_func() noexcept (常量表达式); 

常量表达式的结果会被转换成一个bool类型的值。该值为true,表示函数不会抛出异常,反之,则有可能抛出异常。这里,不带常量表达式的noexcept相当于声明了noexcept(true),即不会抛出异常。

在C++98中,new可能会包含一些抛出的std::bad_alloc异常。

void* operator new(std::size_t) throw(std::bad_alloc);  
void* operator new[](std::size_t) throw(std::bad_alloc);  

而在C++11中,则使用noexcept(false)来进行替代。  

void* operator new(std::size_t) noexcept(false);
void* operator new[](std::size_t) noexcept(false);  

当然,noexcept更大的作用是保证应用程序的安全。比如一个类析构函数不应该抛出异常,那么对于常被析构函数调用的delete函数来说,C++11默认将delete函数设置成noexcept,就可以提高应用程序的安全性。 

void operator delete(void*) noexcept;
void operator delete[](void*) noexcept;  

而同样出于安全考虑,C++11标准中让类的析构函数默认也是noexcept(true)的

另外:

void fun (); // 能抛出任何类型的异常
void fun () throw(except1,except2,except3) // 后面括号里面是一个异常参数表,本例中只能抛出这3中异常
void fun () throw()   // 参数表为空,不能抛出异常

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • C++模板类的用法实例

    C++模板类的用法实例

    这篇文章主要介绍了C++模板类的用法实例,以实例形式详细讲述了模板类的接口、成员、内联函数等概念及用法,需要的朋友可以参考下
    2014-10-10
  • C语言实现txt数据读入内存/CPU缓存实例详解

    C语言实现txt数据读入内存/CPU缓存实例详解

    这篇文章主要介绍了C语言实现txt数据读入内存/CPU缓存实例详解的相关资料,这里对实现该函数进行了代码实现,需要的朋友可以参考下
    2017-01-01
  • Qt 多语言程序设计的实现

    Qt 多语言程序设计的实现

    本文主要介绍了Qt 多语言程序设计的实现,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-01-01
  • 基于C++实现读取指定路径文件

    基于C++实现读取指定路径文件

    这篇文章主要介绍了基于C++实现读取指定路径文件,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07
  • 基于C++实现TCP聊天室功能

    基于C++实现TCP聊天室功能

    这篇文章主要为大家详细介绍了基于C++实现TCP聊天室功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • C++智能指针详解

    C++智能指针详解

    从比较简单的层面来看,智能指针是RAII(Resource Acquisition Is Initialization,资源获取即初始化)机制对普通指针进行的一层封装。这样使得智能指针的行为动作像一个指针,本质上却是一个对象,这样可以方便管理一个对象的生命周期
    2022-08-08
  • 利用Matlab复刻两款粒子爱心动画效果

    利用Matlab复刻两款粒子爱心动画效果

    最近电视剧《点燃我,温暖你》大火,蹭一下热度,发一下MATLAB画爱心的代码,写的比较随意,大家可以自行调整粒子大小和颜色啥的
    2022-11-11
  • VS2019中CMake项目如何指定c++语言标准

    VS2019中CMake项目如何指定c++语言标准

    这篇文章主要介绍了VS2019中CMake项目如何指定c++语言标准,需要的朋友可以参考下
    2020-02-02
  • C++项目求Fibonacci数列的参考解答

    C++项目求Fibonacci数列的参考解答

    今天小编就为大家分享一篇关于C++项目求Fibonacci数列的参考解答,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-02-02
  • C语言实现自动发牌程序

    C语言实现自动发牌程序

    这篇文章主要介绍了利用C语言实现自动发牌程序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-12-12

最新评论