noexcept 关键字

noexcept 的基本语法

noexcept 是
C++11 为了替代 throw() 而提出的一个新的关键字,在
C++ 中使用函数异常声明列表来查看函数可能抛出的异常。比如:

void func() throw (int,double);

上例就是一个函数异常声明列表,该声明指出 func 可能抛出int和 double 类型的异常。但是在实际编程中很少使用这种写法,所以这一特性在 C++11 中被抛弃。另外,如果异常声明列表写成如下形式:

void func() throw();

这种写法表示函数 func 不抛出任何异常,而这种写法在 c++11 中被新的关键字 noexcept 异常声明所取代。

语法上 noexcept 修饰符有两种形式,一种就是简单地在函数声明后加上 noexcept 关键字。比如:

void func() noecept;

另外一种形式则是接受一个常量表达式(参阅《常量表达式》)作为参数,如下所示:

void func() noexcept(常量表达式);

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

noexcept 的使用

noexcept 可以用来阻止异常的传播和扩散,请看下面的例子:


#include

using namespace
std;

void Throw(){ throw 1;}

void NoBlockThrow()
{ 
    Throw();
}

void BlockThrow()noexcept
{
    Throw();
}

int main()
{
    try {
        Throw();
    }
    catch(…) {

        cout << “Found throw.” << endl; // Found throw
    }

    try {
        NoBlockThrow();
    }
    catch(…) {
        cout << “Throw is not blocked” <<endl;
    }

    try {
        BlockThrow();
    }
    catch(…) {
        cout << “Found throw 1” << endl;
    }

    return 0;
}

在上面的例子中,我们定义了 Throw 函数,该函数的唯一作用是抛出一个异常。而 NoBlackThrow 则是一个 noexcept 修饰的函数。

接着,我们再来看一下上面示例的输出结果:

Found throw.

Throw is not blocked

terminate called
after throwing an instance of ‘int’

然后我们分析运行结果可以得到这样的结论:NoBlockThrow会让Throw 函数抛出的异常继续抛出,直到 mian 中的catch 语句将其捕捉。而 BlockThrow 则会直接调用 std::terminate 中断程序的执行从而阻止了异常的继续传播。

注解:std::terminate 用来强制终止进程

而当noexcept 作用于模板时,则增强了 c++ 的泛型编程的能力。例如:

template

void fun() noexcept(noexcept(T()))
{}

上面的模板函数会根据条件实现 noexcept 的修饰版本或者无 noexcept 修饰的版本。fun 函数是否是一个 noexcept 的函数,将由 T() 表达式是否会抛出异常所决定,当第二个 noexcept 参数是一个有可能抛出异常的表达式的时候,其返回值为 false ,这时就实现了无 noexcept 修饰的版本,反之,则是实现了 noexcept 修饰的版本。

noexcept 析构函数中的应用

noexcept 更大的用处就是保证程序的安全。因此出于安全考虑,C++11 标准中类的析构函数默认为 noexcept(true)。但是,如果程序员显式地为析构函数指定了noexcept(false) 或者类的基类或成员有 noexcept(false) 的析构函数,析构函数就不会再保持默认值。

请看下面具体的例子:

#include

using namespace std;

class People {
public:
    ~People() { throw 1;} // warning: throw will always call terminate()
};

class Student {
public:
    ~Student() noexcept(false) {throw 2;}
};

class Singer {
public:
    Student St;
};

int funP() {    People p; }

int funSt(){    Student st; }

int funSi(){    Singer si; }

int main()
{
    try{
        funSt();
    }
    catch(…){
        cout << “caught funSt.” << endl;
    }

    try {
        funSi();
    }
    catch(…) {
        cout << “caught funSi.” << endl;
    }

    try {
        funP();
    }
    catch(…){
        cout << “caught funP” << endl;
    }
    
    return 0;
}

输出结果:

caught funSt.

caught funSi.

terminate called
after throwing an instance of 'int’­

在上面的例子中,无论使析构函数声明为 noexcept(false) 的类 Student 还是包含了 Student 类型成员的类 Singer,它们的析构函数都是可以抛出异常的。只有什么都没有声明的类­­­­­­­ People 的析构函数默认为 noexcept(true),因此阻止了异常的扩散。

  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
noexcept关键字C++11中引入的,用于指明某个函数不会抛出异常。在函数声明或定义时使用noexcept关键字可以明确表示该函数不会抛出任何异常。noexcept关键字有两种形式,一种是直接在函数声明后加上noexcept关键字,例如"void test() noexcept;",另一种是使用noexcept作为操作符,通常用于模板。例如"template <class T> void fun() noexcept(noexcept(T())) {}"。 使用noexcept关键字可以提供更好的代码可读性和性能优化。在函数声明或定义中使用noexcept关键字可以帮助程序员更加清晰地了解函数的异常安全性,并在编译时进行一些优化。当一个函数被声明为noexcept时,编译器可以在编译时对其进行一些优化,提高代码的执行效率。 需要注意的是,noexcept并不会禁止函数抛出异常,而是用来明确表示函数不会抛出异常。如果一个被声明为noexcept的函数在运行时抛出异常,程序将会终止。因此,在使用noexcept关键字时要确保函数的实现没有抛出异常的可能性。 总之,noexcept关键字C++11引入的用于指明某个函数不会抛出异常的关键字,可以提高代码的可读性和性能优化。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [c++中的noexcept 关键字](https://blog.csdn.net/weixin_68294039/article/details/127023089)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [C++ vector扩容解析noexcept应用场景](https://download.csdn.net/download/weixin_38514805/13707167)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值