怎样做seo网站链接/永久免费开网店app

怎样做seo网站链接,永久免费开网店app,美食网站怎么做dw,wordpress自动插件目录 C语言处理错误的方式 C异常的概念 C异常的使用 异常的抛出与捕获匹配原则 函数调用链中的栈展开 异常重新抛出 异常安全 异常规范 标准库异常体系 自定义异常体系 异常的优缺点 C语言处理错误的方式 返回值检查:函数返回特定错误码或值标识失败&am…

目录

C语言处理错误的方式

C++异常的概念

C++异常的使用

异常的抛出与捕获匹配原则

函数调用链中的栈展开 

异常重新抛出 

异常安全

异常规范

标准库异常体系

自定义异常体系

异常的优缺点


C语言处理错误的方式

  1. 返回值检查:函数返回特定错误码或值标识失败,但需逐层检查且易被忽略。

  2. 全局变量 errno:依赖全局变量记录错误类型,存在线程安全隐患和覆盖风险。

  3. 断言(Assert):通过断言验证逻辑假设,但仅适用于调试且失败直接终止程序。

  4. 非局部跳转(setjmp/longjmp):支持跨函数错误跳转,但易导致资源泄漏和代码混乱。

  5. 信号处理:捕获系统信号处理严重错误,但处理函数功能受限且不可靠。

  6. Goto清理:集中释放资源避免冗余,但滥用会破坏代码结构化逻辑。

C++异常的概念

C++ 异常处理是一种用于管理程序运行时错误的机制,它通过分离错误处理代码和正常逻辑来提高代码的可维护性。 

  • try:包裹可能抛出异常的代码块

  • throw:抛出异常对象(任意类型)

  • catch:捕获并处理特定类型的异常

try {// 可能抛出异常的代码if (error) throw MyException("Error occurred");
} 
catch (const MyException& e) {// 处理 MyException 类型异常std::cerr << e.what() << std::endl;
}
catch (...) {  // 捕获所有异常std::cerr << "Unknown error" << std::endl;
}

C++异常的使用

异常的抛出与捕获匹配原则

1、类型精确匹配

  • 异常捕获基于 类型匹配catch 块按顺序尝试匹配异常类型

  • 被选中的处理代码(catch块)是调用链中与该对象类型匹配且离抛出异常位置最近的那一个。
  • 异常是通过抛出对象而引发的,该对象的类型决定了应该激活哪个catch的处理代码,如果抛出的异常对象没有捕获,或是没有匹配类型的捕获,那么程序会终止报错。
try {throw 42;  // 抛出 int 类型异常
}
catch (double d) { /* 不会捕获 */ }
catch (int i) {   // 匹配成功std::cout << "Caught int: " << i;
}

2、继承体系中的匹配

  • 基类 catch 块可以捕获派生类异常(需通过 引用或指针 捕获避免对象切片)

  • 捕获和抛出的异常类型并不一定要完全匹配,可以抛出派生类对象,使用基类进行捕获。
  • 推荐实践:优先捕获派生类异常,再捕获基类

try {throw std::runtime_error("Error");
}
catch (const std::runtime_error& e) {  // 优先匹配具体类型std::cerr << "Runtime error: " << e.what();
}
catch (const std::exception& e) {      // 基类捕获兜底std::cerr << "Standard exception: " << e.what();
}

3、特殊匹配规则

  • catch (...) 捕获所有异常(通常用于资源清理),但捕获后无法知道异常错误是什么。

  • const 修饰不影响匹配:catch (std::exception) 与 catch (const std::exception) 视为相同

函数调用链中的栈展开 

  • 当异常被抛出后,首先检查 throw 本身是否在try块内部,如果在则查找匹配的catch语句,如果有匹配的,则跳到catch的地方进行处理。
  • 如果当前函数栈没有匹配的 catch 则退出当前函数栈,继续在上一个调用函数栈中进行查找匹配的catch。找到匹配的catch子句并处理以后,会沿着 catch 子句后面继续执行,而不会跳回到原来抛异常的地方。
  • 如果到达main函数的栈,依旧没有找到匹配的catch,则终止程序。
void func3() 
{std::vector<int> localObj(100);  // RAII 对象throw std::runtime_error("Boom"); // 抛出异常// localObj 自动析构
}void func2() { func3(); }  // 异常继续传播
void func1() { func2(); }  // 异常继续传播int main() 
{try {func1();}catch (const std::exception& e) {std::cerr << "Caught: " << e.what();}return 0;
}
  1. 函数调用链

    • main() 调用 func1()

    • func1() 调用 func2()

    • func2() 调用 func3()

  2. 异常抛出(func3)

    • 在 func3() 中,首先构造局部对象 std::vector<int> localObj(100)(RAII管理内存)。

    • 执行 throw std::runtime_error("Boom"),抛出异常,函数执行中断。

  3. 栈展开(Stack Unwinding)

    • func3 栈帧销毁localObj 的析构函数自动调用,释放分配的100个int内存(RAII确保资源释放)。

    • func2 栈帧销毁:因无局部对象,直接退出。

    • func1 栈帧销毁:同理,无资源需清理。

  4. 异常捕获(main)

    • 异常传播至 main() 的 try 块。

    • catch (const std::exception& e) 捕获异常(std::runtime_error 是 std::exception 的派生类)。

    • 输出错误信息:Caught: Boom

异常重新抛出 

在 catch 块中使用 throw; 重新抛出当前异常

典型场景

  • 记录日志后继续传播异常

  • 部分处理异常后交由上层处理

异常安全

  1. 构造函数完成对象的构造和初始化,最好不要在构造函数中抛出异常,否则可能导致对象不完整或没有完全初始化。
  2. 析构函数主要完成对象资源的清理,最好不要在析构函数中抛出异常,否则可能导致资源泄露(内存泄露、句柄未关闭等)。
  3. C++中异常经常会导致资源泄露的问题,比如在new和delete中抛出异常,导致内存泄露,在lock和unlock之间抛出异常导致死锁,C++经常使用RAII的方式来解决以上问题。

异常规范

1、优先使用 noexcept

  • 适用场景

    • 移动操作、析构函数、内存释放函数(如 operator delete)。

    • 明确无失败可能的函数(如数学计算)。

double sqrt(double x) noexcept 
{ // 假设输入已校验,不会抛异常return std::sqrt(x); 
}

2. 避免使用动态异常声明

void oldFunc() throw(std::runtime_error); // C++17 已移除,禁止使用
// 替代方案:通过文档说明可能抛出的异常类型。

3、注意事项 

  1. 在函数的后面接throw(type1, type2, ...),列出这个函数可能抛掷的所有异常类型。
  2. 在函数的后面接throw()noexcept(C++11),表示该函数不抛异常。
  3. 若无异常接口声明,则此函数可以抛掷任何类型的异常。(异常接口声明不是强制的)
// 表示func函数可能会抛出A/B/C/D类型的异常
void func() throw(A, B, C, D);// 表示这个函数只会抛出bad_alloc的异常
void* operator new(std::size_t size) throw(std::bad_alloc);// 表示这个函数不会抛出异常
void* operator new(std::size_t size, void* ptr) throw();

标准库异常体系

C++ 标准库提供了一套层次化的异常类体系,所有标准异常均继承自 std::exception 基类。这些异常类型覆盖了常见的程序错误场景,开发者可以直接使用或继承它们实现自定义异常。

std::exception
├── std::bad_alloc                // 内存分配失败(new 失败)
├── std::bad_cast                 // dynamic_cast 转换失败(非多态类型)
├── std::bad_typeid               // typeid 操作符作用于空指针
├── std::ios_base::failure        // I/O 流错误(如文件打开失败)
|
├── std::logic_error              // 程序逻辑错误(可预防的)
│   ├── std::invalid_argument     // 无效参数(如参数不符合预期范围)
│   ├── std::domain_error         // 数学运算定义域错误(如对负数取对数)
│   ├── std::length_error         // 超出允许长度(如 vector::reserve 超过 max_size)
│   └── std::out_of_range         // 访问越界(如 vector::at 越界索引)
|
└── std::runtime_error            // 运行时错误(不可预见的)├── std::range_error          // 计算结果超出有效范围(如浮点数转换溢出)├── std::overflow_error       // 算术上溢错误├── std::underflow_error      // 算术下溢错误└── std::system_error         // 系统调用错误(含错误码,C++11 引入)
  • exception类的 what成员函数 和 析构函数都定义成了虚函数,方便子类对其进行重写,从而达到多态的效果。
  • 我们也可以去继承exception类来实现自己的异常类,但实际中很多公司都会自己定义一套异常继承体系。

 自定义异常:通过继承 std::runtime_error 或 std::logic_error 添加额外信息。

#include <stdexcept>
#include <string>class NetworkException : public std::runtime_error 
{int error_code_;
public:NetworkException(int code, const std::string& message): std::runtime_error(message), error_code_(code) {}int getErrorCode() const noexcept { return error_code_; }
};// 使用
throw NetworkException(404, "Service not found");

代码示例

#include <iostream>
#include <fstream>
#include <stdexcept>
#include <string>void readConfigFile(const std::string& filename) 
{std::ifstream file(filename);if (!file) {throw std::runtime_error("无法打开文件: " + filename);}std::string line;while (std::getline(file, line)) {if (line.empty()) {throw std::invalid_argument("配置文件存在空行");}// 解析配置...}
}int main() 
{try {readConfigFile("settings.conf");}catch (const std::invalid_argument& e) {std::cerr << "参数错误: " << e.what() << std::endl;}catch (const std::runtime_error& e) {std::cerr << "运行时错误: " << e.what() << std::endl;}catch (const std::exception& e) {std::cerr << "标准异常: " << e.what() << std::endl;}return 0;
}

自定义异常体系

实际中很多公司都会自定义自己的异常体系进行规范的异常管理。

  • 公司中的项目一般会进行模块划分,让不同的程序员或小组完成不同的模块,如果不对抛异常这件事进行规范,那么负责最外层捕获异常的程序员就非常难受了,因为他需要捕获大家抛出的各种类型的异常对象。
  • 因此实际中都会定义一套继承的规范体系,先定义一个最基础的异常类,所有人抛出的异常对象都必须是继承于该异常类的派生类对象,因为异常语法规定可以用基类捕获抛出的派生类对象,因此最外层就只需捕获基类就行了。

一、为何需要自定义异常?

  1. 错误分类:为特定领域(如文件I/O、网络、数据库)定义明确的错误类型。

  2. 携带额外信息:在异常对象中封装错误码、文件名、操作步骤等上下文信息。

  3. 统一接口:继承自 std::exception,兼容标准异常处理逻辑。

二、设计原则

  1. 继承标准异常:所有自定义异常应直接或间接继承 std::exception

  2. 层次化结构:按错误类型分层(如 NetworkException 派生出 TimeoutException)。

  3. 支持多态:通过虚函数(如 what())提供统一的错误信息接口。

  4. 异常安全:确保自定义异常类的构造函数和成员函数不抛出异常。

三、实现步骤

1. 基类设计(兼容标准异常) 

#include <exception>
#include <string>class Exception
{
public:// 构造函数(允许传入错误描述)Exception(int errid, const char* errmsg):_errid(errid), _errmsg(errmsg){}int GetErrid() const{return _errid;}// 重写 what(),返回错误信息virtual string what() const{return _errmsg;}
protected:int _errid;     //错误编号string _errmsg; //错误描述//...
};

2. 派生具体异常类

// 文件操作异常
class FileIOException : public Exception 
{
public:explicit FileIOException(const std::string& filename, const std::string& action): Exception("File Error: Failed to " + action + " file '" + filename + "'") {}
};// 网络超时异常
class NetworkTimeoutException : public Exception 
{
public:NetworkTimeoutException(const std::string& url, int timeout_sec): Exception("Network Timeout: Request to '" + url + "' timed out after " + std::to_string(timeout_sec) + " seconds") {}
};

 3使用自定义异常

void readFile(const std::string& filename) 
{std::ifstream file(filename);if (!file.is_open()) {// 抛出异常throw FileIOException(filename, "open");}// 文件操作...
}try 
{readFile("config.yaml");
} 
catch (const FileIOException& e) 
{std::cerr << "文件操作失败: " << e.what() << std::endl;// 尝试恢复或重试
}
catch (const MyBaseException& e) 
{std::cerr << "通用错误: " << e.what() << std::endl;
}

异常的优缺点

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

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

相关文章

【JavaWeb学习Day27】

Tlias前端 员工管理 条件分页查询&#xff1a; 页面布局 搜索栏&#xff1a; <!-- 搜索栏 --><div class"container"><el-form :inline"true" :model"searchEmp" class"demo-form-inline"><el-form-item label…

Python进阶教程丨lambda函数

1. lambda函数是什么&#xff1f; 在 Python 里&#xff0c;lambda 函数是一种特殊类型的函数&#xff0c;也被叫做匿名函数。匿名”意味着它不需要像常规函数那样使用 def 来进行命名。lambda lambda 函数本质上是简洁的临时函数 &#xff0c;它适用于只需要简单逻辑的场景&a…

苹果HFS+56TB存储MOV文件出错的恢复方法

HFS文件系统是Apple电脑中默认的最常见的文件系统。HFS来源于UNIX&#xff0c;优势就是稳定性&#xff0c;另外HFS是支持日志功能的&#xff0c;所以很多存储设备也采用了HFS文件系统。再稳定的文件系统也有“马失前蹄”的时候&#xff0c;下面就来聊下HFS出现文件出错、丢失时…

电源电路篇

电源电路篇 一、LDO-Low Dropout Regulator(低压差线性稳压器)1.1 AMS1117-3.3V芯片 二、DCDC-Direct Current to Direct Current(开关稳压器)2.1 降压(Buck)电路2.1.1 TPS5450-5V芯片 一、LDO-Low Dropout Regulator(低压差线性稳压器) LDO是一种线性稳压器&#xff0c;用于提…

java项目之在线购物系统(源码+文档)

项目简介 在线购物系统实现了以下功能&#xff1a; 使用在线购物系统的用户分管理员和用户两个角色的权限子模块。 管理员所能使用的功能主要有&#xff1a;主页、个人中心、用户管理、商品分类管理、商品信息管理、系统管理、订单管理等。 用户可以实现主页、个人中心、我的…

go语言中空结构体

空结构体(struct{}) 普通理解 在结构体中&#xff0c;可以包裹一系列与对象相关的属性&#xff0c;但若该对象没有属性呢&#xff1f;那它就是一个空结构体。 空结构体&#xff0c;和正常的结构体一样&#xff0c;可以接收方法函数。 type Lamp struct{}func (l Lamp) On()…

Unity实现连连看连线效果

1.一个比较简单的向量计算&#xff0c;用的LineRenderer实现&#xff1b; 已知起始A点和终点C点&#xff0c;求B点&#xff1b; 先计算A点到C点的向量取归一化当做方向&#xff0c;再给定一个“模长”&#xff08;B点到A点的模长&#xff09;乘以该方向&#xff0c;最后加上L…

【MySQL】触发器与存储引擎

目录 触发器基本概念触发器操作创建触发器NEW 与 OLD查看触发器删除触发器 注意事项 存储引擎基本概念基本操作查询当前数据库支持的存储引擎查看当前的默认存储引擎查看某个表用的存储引擎创建表时指定存储引擎修改表的存储引擎 触发器 基本概念 概述&#xff1a; 触发器&a…

能“嘎嘎提升”提升用户居住体验的智能家居物联网框架推荐!

智能家居在日常生活中给我们的带来了更多的便利&#xff0c;更让有些用户切实地体会到了科技的魅力&#xff0c;对于想要打造属于自己的智能家居氛围感的用户们&#xff0c;以下是一些能够帮助提升居住体验的智能家居物联网框架及应用&#xff1a; 1. 涂鸦智能&#xff08;Tuy…

DevEco Studio的使用

目录 1.创建ArkTS工程 2.ArkTS工程目录结构&#xff08;Stage模型&#xff09; 构建第一个页面 构建第二个页面 实现页面间的跳转 1.创建ArkTS工程 若首次打开DevEco Studio&#xff0c;请点击Create Project创建工程。如果已经打开了一个工程&#xff0c;请在菜单栏选择…

性能监控——vmstat

性能监控——vmstat ​ 性能监控是对 IT 系统运行效率和有效性的系统观察和测量。它涉及收集、分析和报告各种组件&#xff08;包括应用程序、网络、服务器和数据库&#xff09;的关键性能指标 (KPI)。此过程使用专门的工具来跟踪响应时间、吞吐量、资源利用率和错误率等指标。…

图像分割的mask有空洞怎么修补

分享一个对实例分割mask修补的方法&#xff0c;希望对大家有所帮助。 1. 这是我准备分割的图片 2 分割结果 可以看到衣服部分有一些没分割出来&#xff0c;二值化图片能清晰看到衣服部分有些黑色未分出的地方。 3 补全mask区域 import cv2 import numpy as npdef fill_mask_h…

Qt 控件概述 QLabel

目录 QLabel显示类控件 label如何做到与窗口同步变化 边框 Frame QLabel显示类控件 ​​ ​​ textFormat &#xff1a;设置文件格式 ​ Pixmap &#xff1a;标签图片 label如何做到与窗口同步变化 Qt中对应用户的操作 &#xff1a; 事件和信号 拖拽窗口大小就会触发…

git 命令回退版本

1、查看提交记录 git log --oneline # 简化的提交历史&#xff08;推荐&#xff09; # 或 git log # 完整提交历史2、版本回退 git reset --hard <commit-hash>3、如果已推送过代码到远程仓库&#xff0c;需强制推送更新 git push -f

浅分析 PE3R 感知高效的三维重建

"近期&#xff0c;二维到三维感知技术的进步显著提升了对二维图像中三维场景的理解能力。然而&#xff0c;现有方法面临诸多关键挑战&#xff0c;包括跨场景泛化能力有限、感知精度欠佳以及重建速度缓慢。为克服这些局限&#xff0c;我们提出了感知高效三维重建框架&#…

汇编与反汇编:DEBUG 命令使用指南

前言 汇编语言是计算机底层编程语言&#xff0c;直接与 CPU 指令集对应。掌握汇编语言和调试工具&#xff08;如DEBUG&#xff09;是深入理解计算机工作原理的关键。本文将介绍汇编与反汇编的基本概念&#xff0c;并详细讲解如何使用 DEBUG 命令进行调试和内存操作。 目录 一、…

栈/堆/static/虚表

在 C 里&#xff0c;栈空间主要用来存放局部变量、函数调用信息等。下面为你介绍栈空间在 C 里的运用方式。 1. 局部变量的使用 在函数内部定义的变量会被存于栈空间&#xff0c;当函数执行结束&#xff0c;这些变量会自动被销毁。 #include <iostream>void exampleFu…

搭建个人博客教程(Hexo)

如何快速搭建一套本地的博客系统呢&#xff1f;这里有一套gitNode.jsHexo的部署方案来进行解决。 安装git Git 是一款免费开源的分布式版本控制系统&#xff0c;由 Linus Torvalds 于 2005 年为 Linux 内核开发设计。它通过本地仓库和远程仓库实现代码管理&#xff0c;支持分支…

鸿蒙NEXT开发问题大全(不断更新中.....)

目录 问题1&#xff1a;鸿蒙NEXT获取华为手机的udid ​问题2&#xff1a;[Fail]ExecuteCommand need connect-key? 问题3&#xff1a;测试时如何安装app包 问题1&#xff1a;鸿蒙NEXT开发获取华为手机的udid hdc -t "设备的序列号" shell bm get --udid 问题2&…

LiteratureReading:[2016] Enriching Word Vectors with Subword Information

文章目录 一、文献简明&#xff08;zero&#xff09;二、快速预览&#xff08;first&#xff09;1、标题分析2、作者介绍3、引用数4、摘要分析&#xff08;1&#xff09;翻译&#xff08;2&#xff09;分析 5、总结分析&#xff08;1&#xff09;翻译&#xff08;2&#xff09;…