C++11 新特性 ---- noexcept

news2024/9/23 5:34:18

1. 异常

异常通常用于处理逻辑上可能发生的错误

在C++98中,提供了一套完善的异常处理机制,直接在程序中将各种类型的异常抛出,从而强制终止程序的运行。

1.1 基本语法

当函数抛出异常时,程序会停止执行,并显示异常信息。异常处理程序可以通过catch语句捕获并处理异常。如果程序没有捕获异常,程序将终止。

在C++中,栈的解旋是在try块中的函数调用完毕后自动完成的。这意味着在try块中的函数调用可能会抛出异常,但不会影响栈的解旋catch块中处理异常时,栈的解旋会被暂停直到catch块处理完毕后栈的解旋才会恢复

#include <iostream>
using namespace std;
void func() {
    int x = 10;
    int* p = &x;
    *p = 20;
    throw *p;
}

void catch_func(int a) {
    std::cout << "Caught exception: " << a << std::endl;
}

int main() {
    try {
        func();
    } catch (int e) {
        catch_func(e);
    }
    return 0;
}
heheda@heheda:~/Linux/c++11$ g++ 8.noexcept.cpp -o app
heheda@heheda:~/Linux/c++11$ ./app
Caught exception: 20

【总结】noexcept | 爱编程的大丙 (subingwen.cn)

异常被抛出后,从进入try块起,到异常被抛掷前,这期间在栈上构造的所有对象,都会被自动析构。析构的顺序与构造的顺序相反。这一过程称为栈的解旋。----来自爱编程的大丙

1.2 异常接口声明

🦝① 显示指定可以抛出的异常类型

divide 函数后添加了 throw 异常接口声明,其参数可以表示抛出的异常类型,分别为 int MyException 类型

#include <iostream>
using namespace std;

struct MyException {
    MyException(string str):msg(str) {}
    string msg;
};

double divide(int a, int b) throw(MyException,int) {
    if(b == 0) {
        throw MyException("divide by zero");
    }
    return a / b;
}

int main() {
    try{
        double val = divide(10, 0);
        cout <<"value: "<< val << endl;
    }catch(int e) {
        cout << "catch except: "  << e << endl;
    }catch(MyException e) {
        cout << "catch except: "  << e.msg << endl;
    }
    return 0;
}

运行结果: 

catch except: divide by zero

🦝② 不抛出任何异常

#include <iostream>
using namespace std;

struct MyException {
    MyException(string str):msg(str) {}
    string msg;
};

double divide(int a, int b) throw() {
    if(b == 0) {
        throw MyException("divide by zero");
    }
    return a / b;
}

int main() {
    try{
        double val = divide(10, 0);
        cout <<"value: "<< val << endl;
    }catch(int e) {
        cout << "catch except: "  << e << endl;
    }catch(MyException e) {
        cout << "catch except: "  << e.msg << endl;
    }
    return 0;
}

divide 函数后添加了throw异常接口声明,其参数列表为空表示该函数不允许抛出异常

2. noexcept

double divisionMethod(int a, int b) noexcept(常量表达式);

🦝① 简单地在函数声明后加上 noexcept 关键字

🦝② 可以接受一个常量表达式作为参数,常量表达式的结果会被转换成一个bool类型的值:

         - 值为 true,表示函数不会抛出异常

         - 值为 false,表示有可能抛出异常这里

         - 不带常量表达式的noexcept相当于声明了noexcept(true),即不会抛出异常

noexcept | 爱编程的大丙 (subingwen.cn)

----来自爱编程的大丙

在C++11中弃用了例如上文的动态异常声明 throw(MyException, int)这一特性,表示函数不会抛出异常的动态异常声明 throw() 也被新的 noexcept 异常声明所取代

noexcept是C++11中引入的一个关键字,用于指定函数抛出异常的情况。当函数声明中使用noexcept时,编译器可以推断函数不会抛出异常,从而提高代码的执行效率。

🦥noexcept 与 throw动态异常声明的区别:

🦝① 基于异常机制的throw()会带来一些额外的开销,若出现函数抛出异常,会导致函数栈被依次地展开(栈解旋),并自动调用析构函数栈上的所有函数

🦝② noexcept 修饰的函数如果抛出了异常,编译器可以选择直接调用 std::terminate() 函数来终止程序的运行,这比基于异常机制的 throw() 在效率上会高一些

#include <iostream>
using namespace std;
void func() noexcept {
  std::cout << "This function does not throw exceptions" << std::endl;
}

int main() {
  try {
     func();
  } catch (...) {
     std::cout << "Exception caught" << std::endl;
  }
  return 0;
}

在这个例子中,func函数使用noexcept关键字指定,因此编译器可以推断出函数不会抛出异常,从而提高代码的执行效率。而main函数中的func调用不会抛出异常,因此程序可以正常运行。

#include <iostream>
using namespace std;

double divide(int a, int b) noexcept {
    if(b == 0) {
        cout << "divide by zero!!!" << endl;
        return -1;
    }
    return a / b;
}

int main() {
    try{
        double val = divide(10, 0);
        cout <<"value: "<< val << endl;
    }catch(int e) {
        cout << "catch except: "  << e << endl;
    }
    return 0;
}
heheda@heheda:~/Linux/c++11$ g++ -std=c++11 8.noexcept.cpp -o app
heheda@heheda:~/Linux/c++11$ ./app
divide by zero!!!
value: -1

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/908720.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【已解决】记 Vue3+SpringBoot 前后端分离项目部署时的一次跨域问题

问题背景是在一次部署开发环境时&#xff0c;由于是前后端分离项目&#xff08;前端Vue3&#xff0c;后端SpringBoot&#xff09;&#xff0c;SpringBoot 使用 Docker 部署&#xff0c;前端访问服务接口时出现跨域问题。 不知道什么是跨域问题的小伙伴可以查看另一篇文章&…

基于5G边缘网关的储能在线监测方案

近年以来&#xff0c;光伏、风力、水力发电等产业发展迅速&#xff0c;新能源在电力市场的占比持续增加&#xff0c;已经成为电力系统的重要组成部分。但由于光伏、风力、水力等发电方式存在天然的波动性&#xff0c;因此也需要配套储能、蓄能系统&#xff0c;保障新能源运行和…

EasyExcel工具 Java导出Excel表数据

EasyExcel 优点坐标依赖读Excel最简单的读的对象写Excel最简单的写的对象最简单的读的监听器填充Excel简单填充(对象)复杂填充(对象和列表)官网:https://easyexcel.opensource.alibaba.com/ EasyExcel是一个基于Java的、快速、简洁、解决大文件内存溢出的Excel处理工具。…

129.【Spring 注解_IOC】

Spring 注解_IOC容器 (一)、组件注册1. Configuration 与 Bean 容器注册组件(1).无注解注入方式(2).注解注入方式 2. ComponentScan 自动扫描组件和自动扫描规则(1).无注解扫描方式(2).注解扫描注入方式(3).指定扫描或不扫描的包 (过滤) 3. 自定义TypeFilter指定过滤规则 Filte…

【stable-diffusion使用扩展+插件和模型资源(上】

文章目录 前言一、插件推荐1.qrcode-monster2.sd-webui-openpose-editor3.sd-webui-depth-lib4.roop&#xff08;换脸插件&#xff09;5.sd-webui-qrcode-toolkit&#xff08;艺术二维码&#xff09;5.光源控制6.二次元转真人7.动态视频转场&#xff08;loopback-wave&#xff…

Unity中实现获取InputField选中的文字

一&#xff1a;前言 获取到选中的文字&#xff1a;哈哈 二&#xff1a;实现 UGUI的InputField提供了selectionAnchorPosition和selectionFocusPosition&#xff0c;开始选择时的光标下标和当前光标下标 using UnityEngine; using UnityEngine.EventSystems; using UnityEngin…

Java之包,权限修饰符,final关键字详解

包 2.1 包 包在操作系统中其实就是一个文件夹。包是用来分门别类的管理技术&#xff0c;不同的技术类放在不同的包下&#xff0c;方便管理和维护。 在IDEA项目中&#xff0c;建包的操作如下&#xff1a; 包名的命名规范&#xff1a; 路径名.路径名.xxx.xxx // 例如&#xff…

视频高效批量剪辑,轻松制作底片效果的视频,实现剪辑自由

大家好&#xff01;在进行视频剪辑时&#xff0c;有时候我们需要对多个视频进行制作底片效果&#xff0c;以便获得更好的视觉效果。为了让您能够轻松制作底片效果视频&#xff0c;我们特别推出了一款便捷工具&#xff0c;让您能够快速制作视频底片效果&#xff0c;实现更加出色…

搞定二叉树

树的名词与概念 子树&#xff1a;树是一个有限集合&#xff0c;子树则是该集合的子集。就像套娃一样&#xff0c;一棵树下面还包含着其子树。比如&#xff0c;树T1 的子树为 树T2、T3、T4&#xff0c;树T2的子树为 T5、T6 。 上图中还有许多子树没有标记出来 。 结点(Node)&am…

wustojc3013字母对应的ASCII 码

#include <stdio.h> int main() {char b;scanf("%c",&b);printf("%d",b);//利用默认强转&#xff0c;字符会打印成ascll码值return 0;}

【韩顺平 零基础30天学会Java】程序流程控制(2days)

day1 程序流程控制&#xff1a;顺序控制、分支控制、循环控制 顺序控制&#xff1a;从上到下逐行地执行&#xff0c;中间没有任何判断和跳转。 Java中定义变量时要采用合法的前向引用。 分支控制if-else&#xff1a;单分支、双分支和多分支。 单分支 import java.util.Scann…

【校招VIP】测试专业课之OSI七层模型

考点介绍&#xff1a; 在 OSI 模型中&#xff0c;每一层都依赖于下一层&#xff0c;并将数据传递给下一层。同时&#xff0c;每一层也可以向上一层提供特定的服务。这种分层结构使得网络管理员可以更轻松地管理网络&#xff0c;同时使得网络协议的设计更加灵活。 『测试专业课…

学习设计模式之观察者模式,但是宝可梦

前言 作者在准备秋招中&#xff0c;学习设计模式&#xff0c;做点小笔记&#xff0c;用宝可梦为场景举例&#xff0c;有错误欢迎指出。 观察者模式 观察者模式定义了一种一对多的依赖关系&#xff0c;一个对象的状态改变&#xff0c;其他所有依赖者都会接收相应的通知。 所…

阿里云通用算力型u1云服务器CPU性能详细说明

​阿里云服务器u1是通用算力型云服务器&#xff0c;CPU采用2.5 GHz主频的Intel(R) Xeon(R) Platinum处理器&#xff0c;通用算力型u1云服务器不适用于游戏和高频交易等需要极致性能的应用场景及对业务性能一致性有强诉求的应用场景(比如业务HA场景主备机需要性能一致)&#xff…

外贸邮箱前缀选择指南:技巧揭秘!

外贸邮箱前缀用什么好&#xff1f;常见的外贸邮箱前缀有 zoho.com.cn&#xff0c; foxmail.com&#xff0c; hotmail.com&#xff0c; outlook.com&#xff0c; yahoo.com等等。那么这些前缀之间又有什么区别呢&#xff1f;选择哪个前缀对外贸业务更有利呢&#xff1f; 首先&am…

如何通过Side Effects来使得你使用Compose变的得心应手?

作者&#xff1a;clwater 虽然我使用Compose已经有了一段时间的, 但我还是觉得使用起来束手束脚的. 究其原因, 大概是coding时的思路还没有完全转换过来, 还没有沉浸在"Compose is Function"之中. 和我们熟悉的View不同, 当我们调用Compose之后, 我们就失去了它的修改…

代码审计-审计工具介绍-DAST+SAST+IAST项目

DASTSASTIAST项目介绍 DAST&#xff1a; 动态应用程序安全测试&#xff08;Dynamic Application Security Testing&#xff09;技术在测试或运行阶段分析应用程序的动态运行状态。它模拟黑客行为对应用程序进行动态攻击&#xff0c;分析应用程序的反应&#xff0c;从而确定该We…

*看门狗2_思考多组看门狗对多任务的监控

多任务系统中 一般结合嵌入式操作系统&#xff0c;设置一个优先级级别最高的任务作为监视器&#xff0c;以监视各个应用任务是否正常运行&#xff0c;该监视器即为软件看门狗&#xff0c;该任务对其他任务都设定一个计时器&#xff0c;每个被监视的任务在设定的时间内对软件看门…

企业级私有化部署即时通讯,完美替代SaaS平台

在数字化转型的时代&#xff0c;企业越来越需要安全、高效和可扩展的解决方案来管理其运营。作为通用办公行业的领军品牌&#xff0c;WorkPlus在企业级私有化部署领域成为改变者。凭借其尖端功能和全面的功能性&#xff0c;WorkPlus提供了传统的软件即服务&#xff08;SaaS&…

SELinux 入门 pt.1

哈喽大家好&#xff0c;我是咸鱼 文章《SELinux 导致 Keepalived 检测脚本无法执行》以【keepalived 无法执行检测脚本】为案例向大家简单介绍了关于 SELinux 的一些概念 比如说什么是自主访问控制 DAC 和 强制访问控制 MAC&#xff1b;SELinux 安全上下文的概念等等 那么今…