c和cpp的异常处理
### 课堂讨论
**老师**:今天我们来深入探讨一下C++的异常处理机制。想象一下,我们正在玩一场探险游戏。你会遇到一些意外情况,比如掉进陷阱。这就像我们的程序在运行中遇到错误。我们该怎么处理呢?🤔
**学生**:嗯,是不是用`try`、`catch`和`throw`?
**老师**:没错!这是我们处理这些“陷阱”的三件法宝。
没错,你总结得很好!我们可以通过这三个关键步骤来理解异常处理:
1. **try块**:这是你放置可能会出错的代码的地方。就像在探险中,你准备尝试穿越一片未知的森林。你知道可能会遇到一些危险,但你还是要前进。
2. **throw表达式**:当在`try`块中发现了问题(比如你遇到了一个大陷阱),你可以用`throw`来“抛出”一个异常,就像发出求救信号,告诉程序这里出了问题。
3. **catch块**:这是用来捕获和处理那些抛出的异常的地方。就像接收到求救信号后,救援队会过来帮你解决问题。你可以针对不同类型的异常写不同的`catch`块,确保每种情况都有相应的解决方案。
首先,`try`块就像踏入未知的森林,你知道可能会有危险,但还是要勇敢前进。你能想到什么场景会用到`try`吗?
**学生**:比如读取文件时,文件可能不存在?
**老师**:正是如此!我们来看一个例子:
```cpp
#include <iostream>
#include <fstream>
#include <stdexcept>
int main() {
try {
std::ifstream file("data.txt");
if (!file) {
throw std::runtime_error("文件未找到!📁❌");
}
// 处理文件...
} catch (const std::runtime_error& e) {
std::cout << "捕获到异常: " << e.what() << '\n';
}
return 0;
}
```
**老师**:在这个例子中,我们尝试打开一个文件。
`std::ofstream` 和 `std::ifstream` 分别是 "output file stream" 和 "input file stream" 的缩写。
- **`std::ofstream`**:
- **Output File Stream**: 用于输出(写入)文件的流。
- **`std::ifstream`**:
- **Input File Stream**: 用于输入(读取)文件的流。
这些流类提供了与文件进行交互的简单接口,允许程序读取和写入文件数据。
当然,这段代码的每一句都可以通过其语法结构来理解:
1. **`#include <iostream>`**
- **语法结构**:预处理指令
- **作用**:包含标准输入输出流库,使得程序可以使用`std::cout`和`std::cin`进行控制台输入输出。
2. **`#include <fstream>`**
- **语法结构**:预处理指令
- **作用**:包含文件流库,允许程序使用文件输入输出流,如`std::ifstream`和`std::ofstream`,用于文件操作。
3. **`#include <stdexcept>`**
- **语法结构**:预处理指令
- **作用**:包含标准异常库,使得程序可以使用标准异常类如`std::runtime_error`,用于抛出和处理异常。
4. **`int main() {`**
- **语法结构**:函数定义
- **作用**:定义程序的入口函数`main`,返回类型为`int`,表示程序的执行状态。大括号`{}`包围了函数的主体。
5. **`try {`**
- **语法结构**:异常处理结构的起始
- **作用**:标记一段可能抛出异常的代码块。程序在此块中执行代码,并在遇到异常时将控制转移到相应的`catch`块。
6. **`std::ifstream file("data.txt");`**
- **语法结构**:对象创建和初始化
- **作用**:创建一个输入文件流对象`file`,并尝试打开名为`data.txt`的文件。`std::ifstream`是一个来自`<fstream>`库的类,用于读取文件。
7. **`if (!file) {`**
- **语法结构**:条件语句
- **作用**:检查文件流对象`file`的状态。如果文件未成功打开(即`file`为假),则进入条件内的代码块。
8. **`throw std::runtime_error("文件未找到!📁❌");`**
- **异常抛出
- **作用**:创建并抛出一个`std::runtime_error`类型的异常,包含错误信息字符串"文件未找到!📁❌"。这将把程序控制转移到`catch`块。
9. **`// 处理文件...`**
- **语法结构**:注释
- **作用**:说明性的文本,供程序员阅读。标识出在这里可以放置处理文件的代码。
10. **`} catch (const std::runtime_error& e) {`**
- **语法结构**:异常捕获
- **作用**:捕获从`try`块中抛出的`std::runtime_error`类型异常。`e`是捕获的异常对象的引用,允许访问异常信息。
在 `catch (const std::runtime_error& e)` 这一部分中,每个部分的意思如下:
- **`const`**: 指定`e`是一个常量引用。这意味着在`catch`块中不能修改`e`所引用的异常对象。这是一个常见的做法,因为通常不需要修改异常对象,只需要读取其中的信息。
- **`std::runtime_error`**: 这是一个标准库中定义的异常类,继承自`std::exception`。它用于表示程序运行时的错误。`std::runtime_error`通常包含一个错误消息,可以通过调用`what()`方法获取。
- **`&`**: 表示引用。这里是捕获异常的引用,使用引用可以避免对象的拷贝,同时也确保使用的是抛出时的异常对象。
- **`e`**: 这是异常对象的名称。在`catch`块中,可以通过这个名字访问捕获的异常对象,通常用于获取错误信息或进行其他异常处理。
在 `catch (const std::runtime_error& e)` 中,`&` 用于声明 `e` 是对抛出的异常对象的引用。这避免了在捕获异常时对异常对象的拷贝。具体来说:
### 避免的拷贝
- **对象拷贝**: 当异常被抛出时,通常会创建一个异常对象。通过使用引用来捕获这个对象,可以避免在 `catch` 块中再次拷贝这个对象,从而提高性能并减少内存使用。这在处理大型对象或者复杂异常类型时尤为重要。
### `&` 的其他意思
1. **取地址符**:
- 用于获取变量的内存地址。
- 例如:`int x = 10; int* ptr = &x;` 这里 `&x` 获取变量 `x` 的地址并赋值给指针 `ptr`。
2. **按位与运算符**:
- 用于对整数执行按位与运算。
- 例如:`int a = 5, b = 3; int c = a & b;` 这里 `a & b` 计算结果为 `1`,因为二进制的按位与运算。
3. **引用符**:
- 用于声明一个变量是引用类型。
- 例如:`int x = 5; int& ref = x;` 这里 `ref` 是 `x` 的引用,允许通过 `ref` 直接访问和修改 `x`。
4. **右值引用(C++11及之后)**:
- 用作右值引用符号(`&&`),用于移动语义。
- 例如:`void foo(int&& x);` 这里 `x` 是一个右值引用,用于实现移动语义以优化性能。
这些不同的用法在语法上和功能上是不同的,具体的含义取决于 `&` 所处的上下文。
总结一下,`catch (const std::runtime_error& e)`的作用是捕获一个类型为`std::runtime_error`的异常,并通过引用`e`来访问异常对象的详细信息,如错误消息。
11. **`std::cout << "捕获到异常: " << e.what() << '\n';`**
- **语法结构**:输出语句
- **作用**:使用标准输出流`std::cout`输出捕获到的异常信息。`e.what()`调用异常对象的方法,返回一个指向异常描述的字符串。`'\n'`用于换行。
12. **`return 0;`**
- **语法结构**:返回语句
- **作用**:从`main`函数返回整数值`0`,表示程序正常结束。C++标准规定,返回`0`通常表示成功执行。
13. **`}`**
- **语法结构**:块结束符
- **作用**:关闭先前打开的`try-catch`块以及`main`函数的定义。
如果文件不存在,我们就`throw`一个异常,这就像发出了求救信号。然后呢,`catch`块就好比救援队,他们接收到信号后会过来帮我们解决问题。😀
**学生**:明白了!那`throw`表达式具体是怎么工作的?
**老师**:`throw`就是在告诉程序“这里有问题”,它会跳出`try`块,把控制权交给相应的`catch`块。再来看一个例子,这次是处理除零错误:
```cpp
#include <iostream>
#include <stdexcept>
double divide(double a, double b) {
if (b == 0) {
throw std::invalid_argument("除数不能为零!❌");
}
return a / b;
}
int main() {
try {
double result = divide(10, 0);
std::cout << "结果是: " << result << '\n';
} catch (const std::invalid_argument& e) {
std::cout << "捕获到异常: " << e.what() << '\n';
}
return 0;
}
```
**学生**:哦,我看到当`b`是零的时候,`throw`就启动了,然后`catch`块捕获并处理了这个问题。
**老师**:没错!`catch`块可以处理特定类型的异常,确保程序不会崩溃。这里用到的是`std::invalid_argument`,专门处理无效参数的问题。😊
**学生**:这让我想到,如果网络请求失败,也可以用这种方式处理?
**老师**:完全正确!假设你在获取一个远程服务器的数据,如果连接失败,你可以抛出一个异常来处理。看这个例子:
```cpp
#include <iostream>
#include <stdexcept>
void fetchDataFromServer() {
// 模拟网络请求失败
bool networkError = true;
if (networkError) {
throw std::runtime_error("网络请求失败!🌐❌");
}
// 处理请求...
}
int main() {
try {
fetchDataFromServer();
} catch (const std::runtime_error& e) {
std::cout << "捕获到异常: " << e.what() << '\n';
}
return 0;
}
```
**学生**:我明白了,`try`、`catch`、`throw`的组合就像一套完整的异常处理系统,帮助我们优雅地处理程序中的意外情况。
**老师**:你总结得很好!这三者的协作使得我们的程序更健壮,也更容易维护。有什么不清楚的地方吗?
**学生**:没有了,这次我完全理解了!谢谢老师!🙌
### 思维导图总结
- **异常处理机制**
- **try块**:执行可能出错的操作
- **throw表达式**:抛出异常,表明错误发生
- **catch块**:捕获并处理异常
### 思考题
1. **问题**:编写一个C++程序,模拟一个购物车系统,尝试从空购物车中移除商品,并使用异常处理来处理这个错误。
**答案**:
```cpp
#include <iostream>
#include <stdexcept>
#include <vector>
void removeItem(std::vector<int>& cart) {
if (cart.empty()) {
throw std::out_of_range("购物车是空的,无法移除商品!🛒❌");
}
cart.pop_back();
}
int main() {
try {
std::vector<int> cart;
removeItem(cart);
} catch (const std::out_of_range& e) {
std::cout << "捕获到异常: " << e.what() << '\n';
}
return 0;
}
```
2. **问题**:解释为什么在处理异常时,`catch`块中的异常类型很重要。
**答案**:`catch`块中的异常类型用于匹配抛出的异常类型。如果异常类型不匹配,`catch`块不会捕获该异常。这允许程序设计者针对不同的错误类型提供不同的解决方案,提高了程序的灵活性和健壮性。根据不同的异常类型提供针对性的处理逻辑,可以更有效地解决问题并提供有用的反馈。
总结:
在C++中,`try-catch`语句用于异常处理。这个机制允许程序在运行时捕获错误,并通过适当的异常处理代码进行处理。以下是一个简单的示例,展示了如何使用`try-catch`来处理异常:
```cpp
#include <iostream> // 包含输入输出流库,用于输入输出操作
#include <stdexcept> // 包含标准异常库,用于处理异常
int main() { // 主函数,程序执行的入口
try { // 尝试执行以下代码块
std::cout << "Trying to do something risky...\n"; // 输出信息到控制台
throw std::runtime_error("An error occurred!"); // 抛出一个运行时错误异常
} catch (const std::runtime_error& e) { // 捕获运行时错误异常
std::cout << "Caught a runtime error: " << e.what() << '\n'; // 输出异常信息
} catch (...) { // 捕获任何其他异常
std::cout << "Caught an unknown exception\n"; // 输出捕获未知异常的信息
}
std::cout << "Continuing execution\n"; // 输出继续执行的信息
return 0; // 返回0,表示程序成功结束
}
```
#### 先修知识
- **C++语法基础**:了解如何定义和使用函数、变量、控制结构等。
- **异常处理**:理解`try-catch`块的用途,用于捕获和处理程序执行中的异常。
- **标准库**:了解C++标准库中的`iostream`和`stdexcept`,前者用于输入输出操作,后者用于异常处理。
### 3. 分类举例说明这个代码用来做什么?
这个代码演示了异常处理的基本用法。通常用于以下场景:
- **错误捕获**:当程序出现不可预见的错误时,通过异常机制捕获错误并进行适当处理,而不是终止程序。
- **资源管理**:在操作文件、网络连接等资源时,异常处理可确保资源被正确释放。
- **输入验证**:在处理用户输入时,使用异常处理机制来捕获和处理无效输入。
### 4. 设计一道类似作用的代码题
#### 题目
编写一个C++程序,尝试打开一个文件读取内容,如果文件不存在或无法打开,抛出异常并捕获,输出相应的错误信息。
#### 设计思路
1. **包含必要库**:需要包含用于文件操作的库。
2. **定义文件名**:使用硬编码的文件名,便于测试。
3. **尝试打开文件**:使用`std::ifstream`尝试打开文件。
4. **抛出异常**:如果文件打开失败,抛出异常。
5. **捕获异常**:使用`try-catch`结构捕获并处理异常。
6. **输出结果**:根据情况输出成功或错误信息。
#### 带逐行注释的代码
```cpp
#include <iostream> // 包含输入输出流库
#include <fstream> // 包含文件流库,用于文件操作
#include <stdexcept> // 包含标准异常库,用于处理异常
int main() {
const char* filename = "example.txt"; // 定义要打开的文件名
try { // 尝试执行以下代码块
std::ifstream file(filename); // 创建文件输入流对象
if (!file) { // 判断文件是否打开成功
throw std::runtime_error("File cannot be opened"); // 抛出异常,文件无法打开
}
std::cout << "File opened successfully.\n"; // 文件打开成功时输出信息
// 可以在此处添加读取文件内容的代码
} catch (const std::runtime_error& e) { // 捕获运行时错误异常
std::cout << "Error: " << e.what() << '\n'; // 输出异常信息
} catch (...) { // 捕获任何其他异常
std::cout << "An unknown error occurred\n"; // 输出未知错误信息
}
std::cout << "Program continues...\n"; // 输出程序继续执行的信息
return 0; // 返回0,表示程序成功结束
}
```
这个程序演示了如何使用异常处理来处理文件操作中的错误情形。当文件无法打开时,程序不会崩溃,而是通过异常机制输出错误信息,并继续执行后续代码。
在C语言中没有直接的`try`语法。`try-catch`结构是用于异常处理的,并且通常是在C++或其他高级语言中使用。在C语言中,异常处理通常通过返回错误代码和使用`setjmp`和`longjmp`函数来实现。以下是一个简单的示例,展示了如何使用`setjmp`和`longjmp`进行错误处理:
```c
#include <stdio.h>
#include <setjmp.h>
jmp_buf buffer;
void errorFunction() {
printf("An error occurred, jumping back!\n");
longjmp(buffer, 1); // Jump back to the saved point
}
int main() {
if (setjmp(buffer) == 0) {
printf("Starting try block\n");
errorFunction(); // Simulate an error
printf("This will not be printed\n");
} else {
printf("Caught an error\n");
}
printf("Continuing execution\n");
return 0;
}
```
在这个例子中,`setjmp`用于保存当前的执行环境,如果调用`longjmp`,则程序会返回到`setjmp`的调用点,并从那里继续执行。这种方法可以模拟类似`try-catch`的行为,但需要手动管理。
相关文章:
c和cpp的异常处理
### 课堂讨论 **老师**:今天我们来深入探讨一下C的异常处理机制。想象一下,我们正在玩一场探险游戏。你会遇到一些意外情况,比如掉进陷阱。这就像我们的程序在运行中遇到错误。我们该怎么处理呢?🤔 **学生**…...

monkey-安卓稳定性测试
一、adb执行命令 1.monkey随机事件指令: adb shell monkey -p com.tytu.enter --ignore-crashes --ignore-timeouts --ignore-security-exceptions -v -v -v --throttle 300 -s 121212 --pct-syskeys 0 --pct-anyevent 0 --pct-touch 100 --pct-motion 0 100000 2&…...

【贪心算法】贪心算法三
贪心算法三 1.买卖股票的最佳时机2.买卖股票的最佳时机 II3.K 次取反后最大化的数组和4.按身高排序5.优势洗牌(田忌赛马) 点赞👍👍收藏🌟🌟关注💖💖 你的支持是对我最大的鼓励&#…...
LeetCode 40-组合总数Ⅱ
题目链接:LeetCode40 欢迎留言交流,每天都会回消息。 class Solution {List<List<Integer>> rs new ArrayList<>();LinkedList<Integer> path new LinkedList<>();public List<List<Integer>> combinatio…...

STM32WB55RG开发(1)----开发板测试
STM32WB55RG开发----1.开发板测试 概述硬件准备视频教学样品申请源码下载产品特性参考程序生成STM32CUBEMX串口配置LED配置堆栈设置串口重定向主循环演示 概述 STM32WB55 & SENSOR是一款基于STM32WB55系列微控制器的评估套件。该套件采用先进的无线通信技术,支…...

误删分区数据恢复全攻略
一、误删分区现象描述 在日常使用电脑的过程中,我们可能会遇到一种令人头疼的情况——误删分区。这通常发生在用户对磁盘管理操作不当,或者在进行系统重装、分区调整时不慎删除了重要分区。误删分区后,原本存储在该分区的数据将无法直接访问…...

《XGBoost算法的原理推导》12-14决策树复杂度的正则化项 公式解析
本文是将文章《XGBoost算法的原理推导》中的公式单独拿出来做一个详细的解析,便于初学者更好的理解。 我们定义一颗树的复杂度 Ω Ω Ω,它由两部分组成: 叶子结点的数量;叶子结点权重向量的 L 2 L2 L2范数; 公式(…...

昇思大模型平台打卡体验活动:项目4基于MindSpore实现Roberta模型Prompt Tuning
基于MindNLP的Roberta模型Prompt Tuning 本文档介绍了如何基于MindNLP进行Roberta模型的Prompt Tuning,主要用于GLUE基准数据集的微调。本文提供了完整的代码示例以及详细的步骤说明,便于理解和复现实验。 环境配置 在运行此代码前,请确保…...
hadoop 3.x 伪分布式搭建
hadoop 伪分布式搭建 环境 CentOS 7jdk 1.8hadoop 3.3.6 1. 准备 准备环境所需包上传所有压缩包到服务器 2. 安装jdk # 解压jdk到/usr/local目录下 tar -xvf jdk-8u431-linux-x64.tar.gz -C /usr/local先不着急配置java环境变量,后面和hadoop一起配置 3. 安装had…...
springboot 整合mybatis
一,引入MyBatis起步依赖 <!--mybatis依赖--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>3.0.0</version></dependency> 二&a…...

餐饮门店收银系统源码、php收银系统源码
1. 系统开发语言 核心开发语言: PHP、HTML5、Dart后台接口: PHP7.3后台管理网站: HTML5vue2.0element-uicssjs线下收银台(安卓/PC收银、安卓自助收银): Dart3框架:Flutter 3.19.6移动店务助手: uniapp线上商城: uniapp 2.系统概况及适用行业…...

canal1.1.7使用canal-adapter进行mysql同步数据
重要的事情说前面,canal1.1.8需要jdk11以上,大家自行选择,我这由于项目原因只能使用1.1.7兼容版的 文章参考地址: canal 使用详解_canal使用-CSDN博客 使用canal.deployer-1.1.7和canal.adapter-1.1.7实现mysql数据同步_mysql更…...

揭秘文心一言,智能助手新体验
一、产品描述 文心一言是一款集先进人工智能技术与自然语言处理能力于一体的智能助手软件。它采用了深度学习算法和大规模语料库训练,具备强大的语义理解和生成能力。通过简洁直观的用户界面,文心一言能够与用户进行流畅的对话交流,理解用户…...

良心无广,这5款才是你电脑上该装的神仙软件,很多人都不知道
图吧工具箱 这是一款完全纯净的硬件检测工具包,体积小巧不足0.5MB,却全面整合了CPU、硬盘、内存、显卡等电脑大神常用的检测工具与压力测试软件。 还特别为游戏爱好者们准备了直达平台官网的链接以及Directx修复工具,而且全部免费哦…...
Scala图书馆创建图书信息
图书馆书籍管理系统相关的练习。内容要求: 1.创建一个可变 Set,用于存储图书馆中的书籍信息(假设书籍信息用字符串表示,如 “Java 编程思想”“Scala 实战” 等),初始化为包含几本你喜欢的书籍。 2.添加两本…...
【Python】深入理解Python中的单例模式:用元类、装饰器和模块实现高效的单例设计
解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 单例模式是一种重要的设计模式,旨在确保一个类的实例在整个应用程序中仅存在一个。Python作为一种动态语言,为实现单例模式提供了多种方式…...

Flutter 小技巧之 Shader 实现酷炫的粒子动画
在之前的《不一样的思路实现炫酷 3D 翻页折叠动画》我们其实介绍过:如何使用 Shader 去实现一个 3D 的翻页效果,具体就是使用 Flutter 在 3.7 开始提供 Fragment Shader API ,因为每个像素都会过 Fragment Shader ,所以我们可以通…...
【LeetCode】【算法】42. 接雨水
LeetCode 42. 接雨水 题目描述 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 示例: 输入:height [0,1,0,2,1,0,1,3,2,1,2,1] 输出:6 解释:上面是由数…...

深⼊理解指针(5)[回调函数、qsort相关知识(qsort可用于各种类型变量的排序)】
目录 1. 回调函数 2. qsort相关知识(qsort可用于各种类型变量的排序) 一 回调函数 1定义/作用:把函数的指针(地址)作为参数传递给另⼀个函数,当这个指针被⽤来调⽤其所指向的函数 时,被调⽤的函数就…...

qt QRunnable 与 QThreadPool详解
1. 概述 QRunnable是所有runnable对象的基类,它表示一个任务或要执行的代码。开发者需要子类化QRunnable并重写其run()函数来实现具体的任务逻辑。而QThreadPool则是一个管理QThread集合的类,它帮助减少创建线程的成本,通过管理和循环使用单…...

龙虎榜——20250610
上证指数放量收阴线,个股多数下跌,盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型,指数短线有调整的需求,大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的:御银股份、雄帝科技 驱动…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...

基于当前项目通过npm包形式暴露公共组件
1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹,并新增内容 3.创建package文件夹...
MVC 数据库
MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖
在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会࿰…...

并发编程 - go版
1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...

C++ 设计模式 《小明的奶茶加料风波》
👨🎓 模式名称:装饰器模式(Decorator Pattern) 👦 小明最近上线了校园奶茶配送功能,业务火爆,大家都在加料: 有的同学要加波霸 🟤,有的要加椰果…...
c# 局部函数 定义、功能与示例
C# 局部函数:定义、功能与示例 1. 定义与功能 局部函数(Local Function)是嵌套在另一个方法内部的私有方法,仅在包含它的方法内可见。 • 作用:封装仅用于当前方法的逻辑,避免污染类作用域,提升…...