当前位置: 首页 > news >正文

异常与c++11中的noexcept【c++】

文章目录

  • 异常
  • try catch 语法
        • 执行流程:
  • 项目中如何使用try catch
  • noexcept
  • 如何解决异常处理中的资源泄漏
      • RAII
        • 自定义 RAII 类管理其他资源(文件、锁、网络连接等)

异常

try catch 语法

将 “可能出错的代码” 与 “错误处理逻辑” 分离

try 负责 “发现问题”,catch 负责 “解决问题”

#include <iostream>
#include <stdexcept>// 可能抛出异常的函数
void read_file(const std::string& filename) {// 模拟“文件不存在”的错误,主动抛出异常if (filename.empty()) {throw std::invalid_argument("文件名不能为空"); // 抛出异常}// 正常逻辑(略)
}int main() {std::string filename = ""; // 无效的文件名try {// try块:标记“可能抛异常”的代码read_file(filename); // 调用可能抛异常的函数std::cout << "文件读取成功(这行不会执行,因为上面抛了异常)" << std::endl;} // catch块1:处理“参数无效”类型的异常catch (const std::invalid_argument& e) {std::cerr << "处理参数错误:" << e.what() << std::endl; // 输出:处理参数错误:文件名不能为空} // catch块2:处理所有其他标准异常(兜底)catch (const std::exception& e) {std::cerr << "处理其他错误:" << e.what() << std::endl;}// 异常处理完成后,继续执行后续代码std::cout << "程序继续运行..." << std::endl;return 0;
}
执行流程:
  1. 执行 try:程序先执行 try 内部的代码(通常是可能出现错误的操作,如文件读写、网络请求、内存分配等)。
  2. 异常抛出:若 try 块中执行到 throw 语句(如 throw std::runtime_error("出错了")),则立即终止 try 块的后续执行,进入 “异常捕获” 阶段。
  3. 匹配 catch:程序从上到下检查 catch 块的 “异常类型”,找到与抛出异常类型匹配的 catch 块,执行其中的错误处理逻辑。
  4. 无异常情况:若 try 块中未抛出任何异常,则所有 catch 块都会被跳过,程序继续执行 catch 块之后的代码

try 本身不处理错误,它的作用是标记一段可能抛出异常的代码范围

在 C++ 异常处理中,e.what() 返回一个描述异常原因的字符串

在实际项目中 ,exception一般是自定义Exception,继承公司的异常规范体系,Exception重写基类(公司的异常规范体系)的虚函数

try 
{// 可能抛出异常的代码
} catch (const std::exception& e) 
{  // e 是捕获到的异常对象// 处理异常
}

项目中如何使用try catch

try_catch/try_catch.md · beihangya/c++4 - 码云 - 开源中国

noexcept

noexcept 是 C++11 引入的关键字,用于指定函数是否可能抛出异常

1 、noexcept:表示函数绝对不会抛出任何异常(也不会允许内部异常传播到外部)。
例:

void func() noexcept { // 函数体内的操作不会抛出异常,或会捕获所有内部异常
}

2、noexcept(表达式):表示函数是否抛出异常由括号内的 “常量表达式” 结果决定true 表示不抛,false 表示可能抛)

// 若 T 的移动构造函数不抛异常,则此函数也不抛
template<typename T>
void move_obj(T& a, T& b) noexcept(noexcept(T(std::move(a)))) 
{b = std::move(a);
}

如何解决异常处理中的资源泄漏

有泄漏风险

void func() {int* ptr = new int(10); // 手动分配内存try {// 若此处抛出异常,delete 不会执行,导致内存泄漏throw std::runtime_error("出错了");delete ptr; // 正常情况下释放内存} catch (...) {// 未处理 ptr 的释放}
}

RAII

#include <memory>void func() {// 智能指针在构造时获取资源,析构时自动释放(即使发生异常)std::unique_ptr<int> ptr(new int(10)); try {throw std::runtime_error("出错了");// 无需手动 delete,ptr 超出作用域时自动释放} catch (...) {// 异常处理,ptr 仍会在函数结束时释放}
}
自定义 RAII 类管理其他资源(文件、锁、网络连接等)

非内存资源(如文件句柄、互斥锁、数据库连接),可封装成 RAII 类,在析构函数中释放资源

#include <cstdio>
#include <stdexcept>// RAII 类:封装文件句柄,析构时自动关闭
class FileGuard {
private:FILE* file;
public:// 构造时打开文件(获取资源)FileGuard(const char* filename, const char* mode) {file = fopen(filename, mode);if (!file) {throw std::runtime_error("文件打开失败");}}// 析构时关闭文件(释放资源,异常安全)~FileGuard() noexcept { // 析构函数不抛异常if (file) {fclose(file); // 确保文件被关闭}}// 禁用拷贝(避免资源被多次释放)FileGuard(const FileGuard&) = delete;FileGuard& operator=(const FileGuard&) = delete;// 提供文件操作接口FILE* get() const { return file; }
};// 使用 RAII 类,无需手动关闭文件
void write_file() {try {FileGuard file("test.txt", "w"); // 打开文件fprintf(file.get(), "hello");    // 操作文件throw std::runtime_error("写入中出错"); // 模拟异常// 无需手动 fclose,FileGuard 析构时自动关闭} catch (const std::exception& e) {std::cerr << e.what() << std::endl;// 异常发生时,file 仍会被析构,文件正常关闭}
}
http://www.dtcms.com/a/436024.html

相关文章:

  • 免费网站制作效果重庆建设施工安全信息网官网
  • 网站设计报价是多少钱网站建设项目计划书
  • Python语言中的应用程序接口(API):本质探析、高级应用与实践范式
  • 小学生做网站下载谷歌浏览器
  • 淄博网站制作高端营销手表网站妨水
  • Spring Boot 常用注解分类整理(含用法示例)
  • 运动网站设计江西商城网站建设
  • 如何做关于网站推广的培训公众号软文怎么写
  • Spring Boot 配置详解:从引导器到注解实战(初学者指南)
  • 网站建设的结论和体会苏州高端建站公司
  • 珠海建设局网站查公司业绩专业h5网站建设教程
  • 136、【OS】【Nuttx】【周边】效果呈现方案解析:strace 日志解析(二)
  • 呼市做网站建设的公司哪家好一个网站成本
  • 洛阳制作网站公司吗wordpress设置内存
  • wordpress vip会员主题企业seo顾问服务公司
  • 《进程概念(1)》
  • 北京企业模板建站南京今天重大新闻事件
  • Pulsar适配AI场景:从技术原理到实战落地
  • 石景山广州网站建设医院网站建设官网
  • 成都做网站的公司弄个小程序要多少钱
  • 手机报价网站大全宣传片拍摄内容
  • BTS7960 四轮前进测试 workable solution
  • 网站架设流程专门app软件制作费用
  • 计算机网站建设维护的目的wordpress 系统需求
  • 无形资产 网站建设官方网站建设与维护好处
  • 程序员用来做笔记的网站网站源码绑定域名
  • 网站建设开发ppt模板德州建设街小学网站
  • 【代码随想录day 34】 力扣 62.不同路径II
  • 哪些公司做网站好河南营销型网站建设
  • 做网站需要写程序绿色营销案例100例