C/C++中函数分装时错误处理的常见方法

 更新时间:2025年06月19日 10:32:35   作者:何曾参静谧  
在 C++ 中处理错误信息时,通常有几种常见的方式,具体选择取决于你的需求、代码风格和项目规范,以下是几种常见的处理方式,希望对大家有所帮助

1. 使用返回值(错误码)

适用于简单函数,尤其是性能敏感的场景。

// 返回 0 表示成功,非 0 表示错误码
int ComputeSomething(int input, double& output) {
    if (input < 0) {
        return 1; // 错误码 1:非法输入
    }
    output = sqrt(input);
    return 0; // 成功
}

// 调用示例:
double result;
int err = ComputeSomething(-1, result);
if (err != 0) {
    std::cerr << "Error: " << err << std::endl;
    // 处理错误...
}

优点:

  • 简单直接,性能高(无异常开销)。
  • 适用于嵌入式或高性能计算。

缺点:

  • 调用者必须检查返回值,容易遗漏。
  • 错误信息不够丰富(只能返回数字代码)。

2. 使用 std::optional 或 std::expected(C++23)

适用于可能失败但不需要详细错误信息的函数。

#include <optional>
#include <cmath>

std::optional<double> SafeSqrt(double x) {
    if (x < 0) {
        return std::nullopt; // 表示失败
    }
    return sqrt(x);
}

// 调用示例:
auto result = SafeSqrt(-1);
if (!result) {
    std::cerr << "Error: Invalid input" << std::endl;
    // 处理错误...
}

优点:

  • 比错误码更清晰,避免魔数(magic numbers)。
  • 适用于可能失败但不需要详细错误信息的场景。

缺点:

无法携带详细的错误信息(只能表示成功/失败)。

3. 抛出异常(throw)

适用于严重错误或不可恢复的错误。

#include <stdexcept>

double ComputeSomething(int input) {
    if (input < 0) {
        throw std::invalid_argument("Input must be non-negative");
    }
    return sqrt(input);
}

// 调用示例:
try {
    double result = ComputeSomething(-1);
} catch (const std::exception& e) {
    std::cerr << "Error: " << e.what() << std::endl;
    // 处理错误...
}

优点:

  • 错误信息丰富(可以携带字符串描述)。
  • 适用于严重错误,避免错误传播。

缺点:

  • 异常处理有额外开销。
  • 滥用异常可能导致代码难以维护。

4. 使用自定义错误结构(结构化错误)

适用于需要返回复杂错误信息的场景。

#include <string>
#include <variant>

// 定义可能的错误类型
struct Error {
    int code;
    std::string message;
};

// 使用 std::variant 表示可能成功或失败
template <typename T>
using Result = std::variant<T, Error>;

Result<double> SafeDivide(double a, double b) {
    if (b == 0) {
        return Error{1, "Division by zero"};
    }
    return a / b;
}

// 调用示例:
auto result = SafeDivide(1, 0);
if (std::holds_alternative<Error>(result)) {
    auto err = std::get<Error>(result);
    std::cerr << "Error " << err.code << ": " << err.message << std::endl;
    // 处理错误...
}

优点:

  • 错误信息结构化(错误码 + 描述)。
  • 适用于需要详细错误信息的 API。

缺点:

  • 需要 C++17(std::variant)。
  • 比错误码稍复杂。

5. 使用日志记录(Logging)

适用于调试或非关键错误。

#include <iostream>

bool ComputeSomething(int input, double& output) {
    if (input < 0) {
        std::cerr << "[ERROR] Input must be non-negative" << std::endl;
        return false;
    }
    output = sqrt(input);
    return true;
}

// 调用示例:
double result;
if (!ComputeSomething(-1, result)) {
    // 错误已打印,无需额外处理
}

优点:

简单直接,适合调试。

缺点:

错误处理不够灵活(日志可能被忽略)。

最佳实践建议

  • 简单错误 → 使用 std::optional 或错误码。
  • 关键错误 → 使用异常(如文件无法打开、内存不足)。
  • 复杂错误 → 使用 std::expected(C++23)或自定义 Result 类型。
  • 调试/日志 → 结合日志记录(如 spdlog 或 std::cerr)。

你的选择应该基于:

  • 性能需求(异常 vs 错误码)。
  • 错误严重程度(可恢复 vs 不可恢复)。
  • 代码可读性(结构化错误 vs 简单错误码)。

到此这篇关于C/C++中函数分装时错误处理的常见方法的文章就介绍到这了,更多相关C/C++错误处理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 手把手教你实现一个C++单链表

    手把手教你实现一个C++单链表

    链表是一种数据结构,用于数据的存储。这篇文章主要为大家介绍了如何实现一个C++单链表,文中的示例代码讲解详细,感兴趣的小伙伴可以尝试一下
    2022-11-11
  • C/C++ Crypto密码库调用的实现方法

    C/C++ Crypto密码库调用的实现方法

    Crypto 库是C/C++的加密算法库,这个加密库很流行,基本上涵盖了市面上的各类加密解密算法,感兴趣的可以参考一下
    2021-06-06
  • 史上最强C语言分支和循环教程详解

    史上最强C语言分支和循环教程详解

    这篇文章主要介绍了史上最强C语言分支和循环教程详解,本文通过代码演示给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-11-11
  • C++ 成员变量的初始化顺序问题详解

    C++ 成员变量的初始化顺序问题详解

    这篇文章主要介绍了C++ 成员变量的初始化顺序问题详解的相关资料,需要的朋友可以参考下
    2017-02-02
  • 深入学习C语言中的函数指针和左右法则

    深入学习C语言中的函数指针和左右法则

    这篇文章主要介绍了深入学习C语言中的函数指针和左右法则,左右法则是一种常用的C指针声明,需要的朋友可以参考下
    2015-08-08
  • C语言实现水波纹效果

    C语言实现水波纹效果

    这篇文章主要为大家详细介绍了C语言实现水波纹效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-02-02
  • C++图书管理系统程序源代码

    C++图书管理系统程序源代码

    这篇文章主要为大家详细介绍了C++图书管理系统程序源代码,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • 关于C++中的友元函数的一些总结

    关于C++中的友元函数的一些总结

    以下是对C++中的友元函数进行了详细的总结介绍,需要的朋友可以过来参考下
    2013-09-09
  • 《C++ primer plus》读书笔记(二)

    《C++ primer plus》读书笔记(二)

    本读书笔记是读了《C++ primer plus(第六版)》第五至八章的学习笔记。是C++读书笔记系列的第二篇。复习C++基础知识的可以瞄瞄。
    2014-10-10
  • C语言数据结构详细解析二叉树的操作

    C语言数据结构详细解析二叉树的操作

    二叉树可以简单理解为对于一个节点来说,最多拥有一个上级节点,同时最多具备左右两个下级节点的数据结构。本文将详细介绍一下C++中二叉树的实现和遍历,需要的可以参考一下
    2022-04-04

最新评论