C++异常学习(二)C++11新特性noexcept学习

1.noexcept()表示函数不会抛出异常的动态异常声明,是C++11中的新特性。

2.C++11之前的异常抛出采用throw(int, double)或者throw(),其中throw(int, double)已被弃用,throw()由noexcept()替代。

3.C++11的noexcept和C++98的throw()使用方法分别如下:

    C++98使用方法:

template<class T> class A {  
  public:  
    static constexpr T min() throw() { return T(); }  
    static constexpr T max() throw() { return T(); }  
    static constexpr T lowest() throw() { return T(); }  
...  

C++11的noexcept使用方法:

template<class T> class A {  
  public:  
    static constexpr T min() noexcept { return T(); }  
    static constexpr T max() noexcept  { return T(); }  
    static constexpr T lowest() noexcept { return T(); }  
...  

4.noexcept(bool),noexcept带一个bool参数或者表达式,若noexcept(true)则表示其所修饰的函数不能抛出异常,

如果noexcept(true)修饰的函数内部抛出了异常,那么noexecpt函数向外抛出了异常(如果函数内部捕捉了异常并完成处理,这种情况不算抛出异常),程序会直接终止,调用std::terminate()函数,该函数内部会调用std::abort()终止程序。从而阻止异常扩散。

  noexcept(false)修饰的函数将抛出异常。

例子如下:

5.

又比如,在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)的。当然,如果程序员显式地为析构函数指定了noexcept,或者类的基类或成员有noexcept(false)的析构函数,析构函数就不会再保持默认值。我们可以看看下面的例子,如下

#include <iostream> 
using namespace std;  
 
struct A {  
    ~A() { throw 1; }  
};  
 
struct B {  
    ~B() noexcept(false) { throw 2; }  
};  
 
struct C {  
    B b;  
};  
 
int funA() { A a; }  
int funB() { B b; }  
int funC() { C c; }  
 
int main() {  
    try {  
        funB();  
    }  
    catch(...){  
        cout << "caught funB." << endl; // caught funB.  
    }  
 
    try {  
        funC();  
    }  
    catch(...){  
        cout << "caught funC." << endl; // caught funC.  
    }  
 
    try {  
        funA(); // terminate called after throwing an instance of 'int'  
    }  
    catch(...){  
        cout << "caught funA." << endl;  
    }  
}  

//在代码中,无论是析构函数声明为noexcept(false)的类B,还是包含了B类型成员的类C,其析构函数都是可以抛出异常的。
//只有什么都没有声明的类A,其析构函数被默认为noexcept(true),从而阻止了异常的扩散。

6.noexcept(表达式),表达式的结果为bool。可以根据表达式的情况进行异常抛出设计。

例如下面的代码:

fun2是否会抛出异常,决定于fun是否会抛出异常。代码首先通过noexcept运算符来计算fun(a,b)是否抛出异常,计算结果是一个布尔值,正好作为noexcept说明符的参数。示例代码如下:

输出结果如下:

 

参考文章:

https://www.cnblogs.com/sword03/p/10020344.html

https://blog.csdn.net/laojiu_/article/details/50781352

https://blog.csdn.net/craftsman1970/article/details/82858285

 

 

 

 

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值