C++ 错误处理:try/catch 及更多——完整指南

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

C++ 错误处理简介

错误处理是开发可靠 C++ 软件的关键任务之一。与某些语言(例如 Python 或 Java)不同,异常是唯一的标准机制,而 C++ 为开发者提供了多种方法。正确策略的选择决定了代码的稳定性、性能和可读性。在本文中,我们将分析经典的 try/catch 结构、C++17/20 标准的现代特性,以及替代的错误处理方法。



1. 经典方法:try/catch 结构

C++ 中异常处理的主要机制基于三个关键字:try、catch 和 throw。异常是任何类型的对象,在发生错误时被“抛出”,并在相应的块中被“捕获”。



#include <iostream>#include <stdexcept>

double divide(double a, double b) { if (b == 0) { throw std::runtime_error("除以零!"); } return a / b;}

int main() { try { double result = divide(10, 0); std::cout << "结果: " << result << std::endl; } catch (const std::runtime_error& e) { std::cerr << "错误: " << e.what() << std::endl; } catch (...) { std::cerr << "未知错误!" << std::endl; } return 0;}


重要事项:

  • 异常层次结构:建议抛出继承自 std::exception 的类对象(例如 std::runtime_error、std::logic_error)。
  • 通过引用捕获:始终通过常量引用捕获异常(const std::exception&),以避免切片和不必要的复制。
  • 通用处理程序:catch (...) 捕获任何异常,但不提供对错误对象的访问。仅将其用作最后的手段。


2. 替代方法:返回码和 std::optional

异常并不总是最佳选择。在高负载系统或嵌入式编程中,通常更倾向于更轻量的机制。



2.1. 返回码 (error codes)

函数返回一个整数或枚举,指示成功或错误类型。这种方法简单高效,但需要显式检查结果。



enum class ErrorCode { Success, DivisionByZero, Overflow };

ErrorCode safe_divide(double a, double b, double& result) { if (b == 0.0) return ErrorCode::DivisionByZero; result = a / b; return ErrorCode::Success;}

int main() { double res; ErrorCode err = safe_divide(10, 0, res); if (err != ErrorCode::Success) { // 错误处理 }}


2.2. std::optional (C++17)

一个可以包含值或为空的容器。非常适合错误意味着没有结果的情况。



#include <optional>

std::optional<double> divide_opt(double a, double b) { if (b == 0.0) return std::nullopt; return a / b;}

int main() { auto result = divide_opt(10, 2); if (result) { std::cout << *result << std::endl; } else { std::cout << "除法错误" << std::endl; }}


3. 现代特性:noexcept 和 std::expected (C++23)

C++ 标准不断发展,为错误处理提供了更具表现力的工具。



3.1. noexcept 规范

关键字 noexcept 指示函数不会抛出异常。这有助于编译器优化代码,并使接口更加清晰。



void l                

博客

书籍推荐