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

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值