C++11中的noexcept关键字,能否不使用异常处理机制?

2026-04-12 07:521阅读0评论SEO资讯
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1108个文字,预计阅读时间需要5分钟。

C++11中的noexcept关键字,能否不使用异常处理机制?

目录+c++11中noexcept关键字+1. 概念+2. 两种形式+3. 异常处理+4. 实现原理+5. 使用场景+c++11关键字noexcept替代throw+c++11中noexcept关键字+1. 概念+noexcept关键字是C++11之后新增加的。该关键字会告知编译器函数不会抛出异常。

目录
  • c++11中noexcept关键字
    • 1. 概念
    • 2. 两种形式
    • 3. 异常处理
    • 4. 实现原理
    • 5. 使用场景
  • c++11关键字noexcept替代throw

    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),并依帧调用在本帧中已构造的自动变量的析构函数等。

    C++11中的noexcept关键字,能否不使用异常处理机制?

    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()   // 参数表为空,不能抛出异常

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持自由互联。

    本文共计1108个文字,预计阅读时间需要5分钟。

    C++11中的noexcept关键字,能否不使用异常处理机制?

    目录+c++11中noexcept关键字+1. 概念+2. 两种形式+3. 异常处理+4. 实现原理+5. 使用场景+c++11关键字noexcept替代throw+c++11中noexcept关键字+1. 概念+noexcept关键字是C++11之后新增加的。该关键字会告知编译器函数不会抛出异常。

    目录
    • c++11中noexcept关键字
      • 1. 概念
      • 2. 两种形式
      • 3. 异常处理
      • 4. 实现原理
      • 5. 使用场景
    • c++11关键字noexcept替代throw

      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),并依帧调用在本帧中已构造的自动变量的析构函数等。

      C++11中的noexcept关键字,能否不使用异常处理机制?

      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()   // 参数表为空,不能抛出异常

      以上为个人经验,希望能给大家一个参考,也希望大家多多支持自由互联。