跳到主要内容
C++ 异常处理机制:异常捕获、自定义异常与实战应用 | 极客日志
C++ 算法
C++ 异常处理机制:异常捕获、自定义异常与实战应用 C++ 异常处理机制涵盖 try-catch-throw 核心语法、标准异常库使用及自定义异常类设计。文章详解异常匹配规则、noexcept 关键字优化、异常传播与重新抛出机制,并结合 RAII 模式与智能指针确保异常安全。通过文件读写实战案例展示分层捕获策略与资源管理,帮助开发者构建高容错性的 C++ 程序,规避内存泄漏与数据不一致风险。
萤火微光 发布于 2026/3/27 更新于 2026/4/25 1 浏览C++ 异常处理机制:异常捕获、自定义异常与实战应用
学习目标与重点
掌握异常处理的核心概念(异常、抛出、捕获、处理)及基本语法,理解 try-catch-throw 语句的执行流程,能够正确捕获和处理标准异常。学会自定义异常类,满足实际开发中的个性化异常场景需求,掌握异常处理的最佳实践,规避常见错误(内存泄漏、异常安全问题)。同时理解异常规格说明(C++11 前)与 noexcept 关键字的使用场景,结合实战案例提升代码的健壮性和容错能力。
💡 核心重点:try-catch 捕获规则、自定义异常的继承设计、异常安全保障、实战场景中的异常处理策略
异常处理概述
什么是异常处理
异常处理是 C++ 中处理程序运行时错误的机制,核心是'将错误检测与错误处理分离'——在程序出错的地方(如除以零、内存分配失败)'抛出'异常,在合适的地方(如主函数、业务逻辑层)'捕获'并处理异常,避免程序直接崩溃,提升代码健壮性。
🗄️ 生活中的异常类比:
快递配送:快递员(程序执行)配送时发现地址错误(异常),不会直接丢弃快递,而是上报快递公司(抛出异常),由客服(异常处理模块)联系收件人解决(处理异常)
餐厅点餐:厨师(程序模块)发现食材耗尽(异常),不会拒绝出餐,而是告知服务员(抛出异常),由服务员(处理模块)向顾客说明并推荐其他菜品(处理异常)
为什么需要异常处理
在异常处理出现前,程序通常通过返回值判断是否出错,但存在明显缺陷:
int divide (int a, int b) {
if (b == 0 ) {
return -1 ;
}
return a / b;
}
int main () {
int result = divide (10 , 0 );
if (result == -1 ) {
cout << "除数不能为 0!" << endl;
} else {
cout << "结果:" << result << endl;
}
;
}
return
0
返回值可能与合法结果冲突(如上述 -1 可能是 divide(-5, 5) 的合法结果)
需手动检查每个函数返回值,代码冗余且易遗漏
错误传播困难(多层函数调用时,需逐层传递错误状态)
错误检测与处理分离,代码结构清晰
异常可跨函数、跨层级传播,无需逐层传递
可携带丰富的错误信息(如错误类型、原因、位置)
避免程序因小错误直接崩溃,提升用户体验
C++ 异常处理的核心组件
throw:抛出异常(检测到错误时,触发异常)
try:尝试执行可能抛出异常的代码块(异常检测范围)
catch:捕获并处理异常(匹配对应的异常类型,执行处理逻辑)
✅ 核心流程:try 块中执行代码 → 若发生错误,throw 抛出异常 → 程序跳转到最近的匹配 catch 块 → 执行 catch 中的处理逻辑 → 处理完成后,程序从 catch 块后继续执行
异常处理基本语法与执行流程
基本语法格式 try {
可能出错的操作;
if (错误条件) {
throw 异常值;
}
} catch (异常类型 1 异常变量) {
} catch (异常类型 2 异常变量) {
} catch (...) {
}
try 块:必须紧跟一个或多个 catch 块,不能单独存在
throw 表达式:可抛出任意类型的值(基本类型、字符串、自定义类),抛出后立即终止当前函数执行,跳转到匹配的 catch 块
catch 块:按顺序匹配异常类型,匹配成功则执行对应处理逻辑;catch (...) 是万能捕获,需放在所有 catch 块最后
异常变量:可选(如 catch (int) 可省略变量名),用于获取抛出的异常信息
执行流程详解 #include <iostream>
using namespace std;
int divide (int a, int b) {
if (b == 0 ) {
throw string ("错误:除数不能为 0!" );
}
return a / b;
}
int main () {
int x = 10 , y = 0 ;
try {
cout << "尝试执行除法运算..." << endl;
int result = divide (x, y);
cout << x << " / " << y << " = " << result << endl;
} catch (const string& err_msg) {
cout << "捕获到异常:" << err_msg << endl;
} catch (...) {
cout << "捕获到未知异常!" << endl;
}
cout << "程序继续执行..." << endl;
return 0 ;
}
尝试执行除法运算...
捕获到异常:错误:除数不能为 0!
程序继续执行...
执行流程拆解:
程序进入 try 块,执行 divide(10, 0)
divide 函数检测到 b=0,throw 抛出 string 类型异常
程序立即终止 try 块执行,跳转到 main 函数中最近的 catch 块
第一个 catch 块匹配 string 类型异常,执行处理逻辑(打印错误信息)
catch 块执行完成后,程序从 catch 块后继续执行(打印'程序继续执行…')
异常的匹配规则 catch 块按声明顺序 匹配异常类型,匹配规则如下:
精确匹配:异常类型与 catch 声明类型完全一致(如 throw int(5) 匹配 catch (int))
派生类匹配:抛出的派生类异常可被基类类型的 catch 块捕获(如自定义异常类继承自 exception,可被 catch (exception&) 捕获)
类型转换匹配:仅支持有限的隐式转换(如 char 可转换为 int,但 int 不能转换为 double)
catch (...) 匹配所有未被前面 catch 块捕获的异常,必须放在最后
⚠️ 警告:catch 块的声明顺序至关重要,若将基类异常的 catch 块放在派生类之前,会导致派生类异常被基类 catch 块捕获,派生类的 catch 块永远无法执行:
class BaseException {};
class DerivedException : public BaseException {};
try {
throw DerivedException ();
} catch (BaseException& e) {
cout << "基类异常" << endl;
} catch (DerivedException& e) {
cout << "派生类异常" << endl;
}
标准异常库 C++ 标准库提供了一系列预定义的异常类,均继承自 std::exception 基类,定义在 <exception> 头文件中,常用标准异常如下:
异常类 描述 适用场景 std::exception所有标准异常的基类 兜底捕获标准异常 std::logic_error逻辑错误(编译期可检测,但未避免) 如无效参数、非法状态 std::invalid_argument无效参数错误 如向函数传递非法参数 std::out_of_range超出范围错误 如数组索引越界、string 下标越界 std::runtime_error运行时错误(编译期无法检测) 如除以零、文件打开失败 std::overflow_error溢出错误 如数值计算溢出 std::bad_alloc内存分配失败错误 如 new 分配内存失败
#include <iostream>
#include <exception>
#include <vector>
using namespace std;
int main () {
vector<int > nums = {1 , 2 , 3 };
try {
cout << "访问索引 3 的元素:" << nums.at (3 ) << endl;
} catch (const out_of_range& e) {
cout << "捕获到 out_of_range 异常:" << e.what () << endl;
} catch (const exception& e) {
cout << "捕获到标准异常:" << e.what () << endl;
}
try {
while (true ) {
new int [1024 * 1024 ];
}
} catch (const bad_alloc& e) {
cout << "捕获到 bad_alloc 异常:" << e.what () << endl;
}
return 0 ;
}
捕获到 out_of_range 异常:vector::_M_range_check: __n (which is 3 ) >= this ->size() (which is 3 )
捕获到 bad_alloc 异常:std::bad_alloc
💡 技巧:标准异常类的 what() 方法返回 C 风格字符串(const char*),包含异常的简要描述,可用于日志输出或用户提示。
自定义异常类 标准异常类虽能满足常见场景,但实际开发中,我们常需要自定义异常(如业务相关的'用户不存在异常''权限不足异常'),自定义异常类需遵循以下原则:
自定义异常的设计原则
继承自标准异常类(推荐 std::exception 或其派生类),便于统一捕获
重写 what() 方法,返回自定义的异常描述信息
提供必要的构造函数(默认构造、带错误信息的构造)
异常类名清晰,体现异常类型(如 UserNotFoundException)
自定义异常类的实现 #include <iostream>
#include <exception>
#include <string>
using namespace std;
class BusinessException : public exception {
private :
string err_msg;
public :
BusinessException (const string& msg) : err_msg (msg) {}
const char * what () const noexcept override {
return err_msg.c_str ();
}
};
class UserNotFoundException : public BusinessException {
public :
UserNotFoundException (int user_id) : BusinessException ("用户不存在:ID=" + to_string (user_id)) {}
};
class PermissionDeniedException : public BusinessException {
public :
PermissionDeniedException (const string& username, const string& operation)
: BusinessException ("权限不足:用户\"" + username + "\"无法执行\"" + operation + "\"操作" ) {}
};
void query_user (int user_id) {
if (user_id < 1000 || user_id > 9999 ) {
throw UserNotFoundException (user_id);
}
cout << "查询成功:用户 ID=" << user_id << endl;
}
void execute_sensitive_operation (const string& username) {
if (username != "admin" ) {
throw PermissionDeniedException (username, "删除数据" );
}
cout << "操作成功:用户\"" << username << "\"执行删除数据操作" << endl;
}
int main () {
try {
query_user (123 );
} catch (const UserNotFoundException& e) {
cout << "业务异常:" << e.what () << endl;
} catch (const BusinessException& e) {
cout << "业务异常:" << e.what () << endl;
} catch (const exception& e) {
cout << "系统异常:" << e.what () << endl;
}
cout << endl;
try {
execute_sensitive_operation ("test" );
} catch (const PermissionDeniedException& e) {
cout << "业务异常:" << e.what () << endl;
} catch (const BusinessException& e) {
cout << "业务异常:" << e.what () << endl;
} catch (const exception& e) {
cout << "系统异常:" << e.what () << endl;
}
return 0 ;
}
业务异常:用户不存在:ID=123
业务异常:权限不足:用户"test" 无法执行"删除数据" 操作
自定义异常的优势
语义清晰 :异常类名直接体现异常类型,代码可读性更高
层次分明 :通过继承关系组织异常(如业务异常→用户异常→权限异常),便于分类处理
信息丰富 :可在构造函数中拼接详细的错误信息(如用户 ID、操作名称),便于问题排查
兼容标准 :继承自 std::exception,可与标准异常一起捕获,统一异常处理逻辑
自定义异常类的 what() 方法必须重写为 const noexcept,符合 std::exception 基类的接口规范
异常类应尽量轻量,避免复杂的成员变量和构造逻辑(异常抛出时会拷贝异常对象)
优先使用引用捕获异常(catch (const Exception& e)),避免拷贝开销,且支持多态匹配
异常处理的高级特性
异常规格说明(C++11 前)与 noexcept
异常规格说明(已废弃) C++11 前,可通过 throw(类型列表) 声明函数可能抛出的异常类型,称为'异常规格说明':
void func () throw (int , string) {
}
void func2 () throw () {
}
若函数抛出了异常规格说明之外的异常,会调用 std::unexpected() 函数,默认终止程序
编译期不强制检查,仅为程序员提供文档说明,实用性有限
C++11 已废弃该语法,推荐使用 noexcept 关键字
noexcept 关键字(C++11 及以上)noexcept 用于声明函数是否可能抛出异常,语法更简洁、功能更明确:
void func () noexcept {
}
void func2 () noexcept (false ) {
}
template <typename T>
void func3 () noexcept (noexcept (T(std::move(T())))) {
}
编译器优化 :若函数声明为 noexcept,编译器可省略异常处理相关的代码(如栈展开),提升性能
明确接口契约 :告知调用者该函数无需处理异常,简化调用逻辑
影响标准库行为 :如 std::vector 的 push_back 若元素的移动构造函数是 noexcept,会使用移动语义(更高效),否则使用拷贝语义
⚠️ 警告:若 noexcept 函数实际抛出了异常,程序会调用 std::terminate() 终止,无法通过 try-catch 捕获,因此需确保 noexcept 函数确实不会抛出异常。
异常的传播与重新抛出
异常的跨函数传播 异常抛出后,若当前函数没有匹配的 catch 块,异常会向上传播到调用该函数的上层函数,直到找到匹配的 catch 块;若传播到 main 函数仍未捕获,程序会调用 std::terminate() 终止。
#include <iostream>
#include <string>
using namespace std;
void func3 () {
cout << "func3:抛出异常" << endl;
throw string ("来自 func3 的异常" );
}
void func2 () {
cout << "func2:调用 func3" << endl;
func3 ();
cout << "func2:执行完毕(不会执行)" << endl;
}
void func1 () {
cout << "func1:调用 func2" << endl;
try {
func2 ();
} catch (const int & e) {
cout << "func1:捕获 int 类型异常" << endl;
}
cout << "func1:执行完毕" << endl;
}
int main () {
cout << "main:调用 func1" << endl;
try {
func1 ();
} catch (const string& e) {
cout << "main:捕获 string 类型异常:" << e << endl;
} catch (...) {
cout << "main:捕获未知异常" << endl;
}
cout << "main:程序结束" << endl;
return 0 ;
}
main :调用 func1
func1:调用 func2
func2:调用 func3
func3:抛出异常
main :捕获 string 类型异常:来自 func3 的异常
main :程序结束
异常的重新抛出 有时需要在 catch 块中处理部分逻辑后,将异常重新抛出给上层函数处理,使用 throw; (不带参数)实现:
#include <iostream>
#include <string>
using namespace std;
void process_data (int data) {
if (data < 0 ) {
throw string ("数据非法:负数不允许" );
}
cout << "数据处理成功:" << data << endl;
}
void handle_request (int data) {
try {
process_data (data);
} catch (const string& e) {
cout << "日志记录:发生异常 - " << e << endl;
throw ;
}
}
int main () {
try {
handle_request (-5 );
} catch (const string& e) {
cout << "用户提示:操作失败,原因:" << e << endl;
}
return 0 ;
}
日志记录:发生异常 - 数据非法:负数不允许
用户提示:操作失败,原因:数据非法:负数不允许
throw; 重新抛出的是原始异常对象,不会创建新的异常对象
若在 catch 块外使用 throw;,会抛出 std::bad_exception 异常
重新抛出时,异常类型不变,上层函数需按原类型捕获
异常安全
不会发生内存泄漏(已分配的内存被正确释放)
数据状态一致(不会出现部分修改的无效状态)
资源被正确释放(如文件句柄、网络连接、锁)
常见的异常安全问题
void unsafe_func () {
int * p = new int (10 );
process_data (-5 );
delete p;
}
异常安全的解决方案
使用智能指针 (推荐):智能指针(如 std::unique_ptr、std::shared_ptr)会在析构时自动释放内存,即使发生异常也不会泄漏
资源获取即初始化(RAII) :将资源(如文件、锁)封装在类中,通过构造函数获取资源,析构函数释放资源,利用类的生命周期管理资源
使用容器和标准库组件 :标准库组件(如 vector、string)均具备异常安全性,避免手动管理资源
#include <iostream>
#include <memory>
#include <string>
using namespace std;
void safe_func () {
unique_ptr<int > p (new int (10 )) ;
throw string ("测试异常安全" );
}
int main () {
try {
safe_func ();
} catch (const string& e) {
cout << "捕获异常:" << e << endl;
}
return 0 ;
}
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
class FileGuard {
private :
ofstream file;
public :
FileGuard (const string& filename) : file (filename) {
if (!file.is_open ()) {
throw string ("文件打开失败:" + filename);
}
cout << "文件打开成功:" << filename << endl;
}
~FileGuard () {
if (file.is_open ()) {
file.close ();
cout << "文件关闭成功" << endl;
}
}
void write (const string& content) {
file << content << endl;
}
};
void write_file (const string& filename, const string& content) {
FileGuard file (filename) ;
file.write (content);
throw string ("模拟写入过程中异常" );
}
int main () {
try {
write_file ("test.txt" , "Hello, 异常安全!" );
} catch (const string& e) {
cout << "捕获异常:" << e << endl;
}
return 0 ;
}
文件打开成功:test.txt
文件关闭成功
捕获异常:模拟写入过程中异常
✅ 结论:即使在写入过程中抛出异常,FileGuard 对象会被析构,文件资源被正确释放,实现了异常安全。
异常处理的常见错误与最佳实践
常见错误
错误 1:过度使用异常 将异常用于正常的控制流(如判断函数返回结果),导致代码效率降低、可读性变差:
int find_element (const vector<int >& vec, int target) {
for (int i = 0 ; i < vec.size (); ++i) {
if (vec[i] == target) {
return i;
}
}
throw string ("元素未找到" );
}
错误 2:捕获所有异常却不处理 使用 catch (...) 捕获所有异常,但未做任何处理,导致问题排查困难:
try {
risky_operation ();
} catch (...) {
}
错误 3:抛出非异常类型的对象 抛出基本类型(如 int、double)或未继承自 std::exception 的自定义类,导致异常处理不统一:
错误 4:异常对象切片 按值捕获异常(catch (BaseException e)),而非按引用捕获,导致派生类异常的特有信息丢失:
class DerivedException : public BaseException {
public :
const char * what () const noexcept override {
return "派生类异常" ;
}
};
try {
throw DerivedException ();
} catch (BaseException e) {
cout << e.what () << endl;
}
最佳实践
实践 1:明确异常使用场景 仅在'异常情况'(如内存分配失败、非法参数、IO 错误)使用异常,正常控制流(如元素未找到、用户输入错误)使用返回值或其他方式处理。
实践 2:优先使用标准异常或自定义异常类
系统级错误(如内存分配、数组越界)使用标准异常类
业务级错误(如用户不存在、权限不足)使用自定义异常类,且继承自 std::exception
实践 3:按引用捕获异常 使用 catch (const Exception& e) 捕获异常,避免拷贝开销和对象切片,支持多态匹配。
实践 4:合理组织 catch 块顺序
派生类异常的 catch 块放在前面
基类异常的 catch 块放在后面
catch (...) 作为兜底,放在最后,并记录日志或终止程序
实践 5:保证异常安全
使用智能指针和 RAII 模式管理资源,避免内存泄漏
重要操作(如数据库事务)需实现回滚机制,确保异常发生时数据状态一致
实践 6:记录异常信息 捕获异常后,记录详细的异常信息(如异常类型、错误描述、发生位置、调用栈),便于问题排查。
实践 7:避免在析构函数中抛出异常 析构函数若抛出异常,可能导致程序终止(如在栈展开过程中,析构函数抛出异常会调用 std::terminate()):
class BadClass {
public :
~BadClass () {
throw string ("析构函数异常" );
}
};
实战案例:文件读写的异常处理
问题描述 实现一个文件读写工具类,支持读取文件内容和写入文件内容,要求:
处理文件操作中的常见异常(文件不存在、权限不足、磁盘已满等)
使用自定义异常类,提供详细的错误信息
保证异常安全(文件资源正确释放)
提供友好的用户提示和日志记录
实现思路
自定义文件相关异常类(继承自 std::exception):FileOpenException(文件打开失败)、FileReadException(文件读取失败)、FileWriteException(文件写入失败)
基于 RAII 模式实现文件工具类 FileHandler,管理文件流资源
实现 read_file 和 write_file 方法,抛出对应的自定义异常
在主函数中捕获异常,记录日志并提示用户
代码实现 #include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <exception>
using namespace std;
class FileException : public exception {
protected :
string err_msg;
public :
FileException (const string& filename, const string& reason) {
err_msg = "文件操作异常:文件\"" + filename + "\", 原因:" + reason;
}
const char * what () const noexcept override {
return err_msg.c_str ();
}
};
class FileOpenException : public FileException {
public :
FileOpenException (const string& filename, const string& reason)
: FileException (filename, "打开失败 - " + reason) {}
};
class FileReadException : public FileException {
public :
FileReadException (const string& filename, const string& reason)
: FileException (filename, "读取失败 - " + reason) {}
};
class FileWriteException : public FileException {
public :
FileWriteException (const string& filename, const string& reason)
: FileException (filename, "写入失败 - " + reason) {}
};
class FileHandler {
private :
string filename;
fstream file_stream;
public :
FileHandler (const string& filename, ios_base::openmode mode) : filename (filename) {
file_stream.open (filename, mode);
if (!file_stream.is_open ()) {
throw FileOpenException (filename, "无法打开文件(可能不存在或权限不足)" );
}
cout << "日志:文件\"" << filename << "\"打开成功" << endl;
}
~FileHandler () {
if (file_stream.is_open ()) {
file_stream.close ();
cout << "日志:文件\"" << filename << "\"关闭成功" << endl;
}
}
vector<string> read_file () {
vector<string> content;
string line;
if (!file_stream.good ()) {
throw FileReadException (filename, "文件流状态异常" );
}
while (getline (file_stream, line)) {
content.push_back (line);
}
if (file_stream.bad ()) {
throw FileReadException (filename, "读取过程中发生 IO 错误" );
}
cout << "日志:文件\"" << filename << "\"读取完成,共" << content.size () << "行" << endl;
return content;
}
void write_file (const vector<string>& content) {
if (!file_stream.good ()) {
throw FileWriteException (filename, "文件流状态异常" );
}
for (const string& line : content) {
file_stream << line << endl;
if (file_stream.fail ()) {
throw FileWriteException (filename, "写入数据失败(可能磁盘已满)" );
}
}
file_stream.flush ();
if (file_stream.fail ()) {
throw FileWriteException (filename, "刷新缓冲区失败" );
}
cout << "日志:文件\"" << filename << "\"写入完成,共" << content.size () << "行" << endl;
}
};
void print_file_content (const vector<string>& content) {
cout << "\n文件内容:" << endl;
for (int i = 0 ; i < content.size (); ++i) {
cout << "[" << i + 1 << "] " << content[i] << endl;
}
cout << endl;
}
int main () {
string read_filename = "input.txt" ;
string write_filename = "output.txt" ;
try {
FileHandler reader (read_filename, ios::in) ;
vector<string> content = reader.read_file ();
print_file_content (content);
vector<string> new_content = {
"=== 新写入的内容 ===" ,
"原文件共" + to_string (content.size ()) + "行" ,
"这是第一行新内容" ,
"这是第二行新内容"
};
FileHandler writer (write_filename, ios::out | ios::trunc) ;
writer.write_file (new_content);
FileHandler verify_reader (write_filename, ios::in) ;
vector<string> verify_content = verify_reader.read_file ();
print_file_content (verify_content);
} catch (const FileOpenException& e) {
cout << "\n错误提示:" << e.what () << endl;
} catch (const FileReadException& e) {
cout << "\n错误提示:" << e.what () << endl;
} catch (const FileWriteException& e) {
cout << "\n错误提示:" << e.what () << endl;
} catch (const exception& e) {
cout << "\n系统错误:" << e.what () << endl;
} catch (...) {
cout << "\n未知错误:发生未预期的异常" << endl;
}
return 0 ;
}
运行结果(正常情况) 日志:文件"input.txt" 打开成功
日志:文件"input.txt" 读取完成,共 3 行
文件内容:
[1 ] Hello, File Handling!
[2 ] This is a test file .
[3 ] C++ Exception Handling.
日志:文件"input.txt" 关闭成功
日志:文件"output.txt" 打开成功
日志:文件"output.txt" 写入完成,共 4 行
日志:文件"output.txt" 关闭成功
日志:文件"output.txt" 打开成功
日志:文件"output.txt" 读取完成,共 4 行
文件内容:
[1 ] === 新写入的内容 ===
[2 ] 原文件共 3 行
[3 ] 这是第一行新内容
[4 ] 这是第二行新内容
日志:文件"output.txt" 关闭成功
异常情况测试(如 input.txt 不存在) 错误提示:文件操作异常:文件"input.txt" , 原因:打开失败 - 无法打开文件(可能不存在或权限不足)
✅ 结论:该文件工具类通过自定义异常类提供了详细的错误信息,基于 RAII 模式保证了文件资源的正确释放,即使发生异常也不会导致资源泄漏,同时通过分层捕获异常,为用户提供了友好的提示,符合异常处理的最佳实践。
总结
异常处理是 C++ 处理运行时错误的核心机制,通过 try-catch-throw 实现错误检测与处理的分离,提升代码健壮性。
标准异常库提供了一系列预定义异常类(如 out_of_range、bad_alloc),自定义异常类应继承自 std::exception,重写 what() 方法。
异常的匹配遵循精确匹配、派生类匹配规则,catch 块需按'派生类在前、基类在后'的顺序声明,catch (...) 作为兜底。
异常安全是关键,需通过智能指针、RAII 模式管理资源,避免内存泄漏和数据不一致。
最佳实践:明确异常使用场景、按引用捕获异常、记录异常信息、避免在析构函数中抛出异常。
通过本文学习,你应能熟练运用异常处理机制解决实际开发中的错误处理问题,编写健壮、可靠的 C++ 代码。下一篇将深入探讨 C++ 的输入输出流(IO 流),包括文件 IO、字符串 IO 等高级应用!
相关免费在线工具 加密/解密文本 使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
Gemini 图片去水印 基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
Markdown转HTML 将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
HTML转Markdown 将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online