跳转到内容

C++ throw 语句

来自代码酷
Admin留言 | 贡献2025年4月28日 (一) 21:26的版本 (Page creation by admin bot)

(差异) ←上一版本 | 已核准修订 (差异) | 最后版本 (差异) | 下一版本→ (差异)

C++ throw语句[编辑 | 编辑源代码]

throw语句是C++异常处理机制的核心组成部分,它允许程序员在检测到异常情况时主动抛出异常对象,将控制权转移给异常处理代码(catch块)。本文将从基础到高级全面讲解throw语句的用法、原理和最佳实践。

基本概念[编辑 | 编辑源代码]

在C++中,当程序遇到无法正常处理的错误条件时,可以通过throw语句抛出异常(throw an exception)。这个异常可以被调用栈中任意层次的try-catch块捕获并处理。

throw语句的基本语法形式:

throw expression;

其中expression可以是任意类型的对象,但通常建议使用标准异常类或自定义异常类。

基本用法示例[编辑 | 编辑源代码]

抛出内置类型异常[编辑 | 编辑源代码]

最简单的throw语句可以抛出基本类型:

#include <iostream>

double divide(double a, double b) {
    if (b == 0.0) {
        throw "Division by zero!";  // 抛出const char*类型异常
    }
    return a / b;
}

int main() {
    try {
        std::cout << divide(10, 0) << std::endl;
    } catch (const char* msg) {
        std::cerr << "Error: " << msg << std::endl;
    }
    return 0;
}

输出:

Error: Division by zero!

抛出标准异常[编辑 | 编辑源代码]

更推荐的做法是使用标准库中的异常类:

#include <iostream>
#include <stdexcept>

double divide(double a, double b) {
    if (b == 0.0) {
        throw std::runtime_error("Division by zero!");
    }
    return a / b;
}

int main() {
    try {
        std::cout << divide(10, 0) << std::endl;
    } catch (const std::exception& e) {
        std::cerr << "Standard exception: " << e.what() << std::endl;
    }
    return 0;
}

输出:

Standard exception: Division by zero!

异常传播机制[编辑 | 编辑源代码]

当throw语句执行时,C++运行时系统会执行以下操作: 1. 终止当前函数的执行 2. 在调用栈中向上查找匹配的catch块 3. 如果找到匹配的catch块,则执行其中的代码 4. 如果未找到,则调用std::terminate()终止程序

graph TD A[throw语句执行] --> B{当前函数有catch块?} B -->|是| C[检查是否匹配] B -->|否| D[栈展开] C -->|匹配| E[执行catch块] C -->|不匹配| D D --> F{调用栈中有try块?} F -->|是| G[检查catch块] F -->|否| H[调用terminate] G -->|匹配| E G -->|不匹配| D

高级用法[编辑 | 编辑源代码]

抛出类对象[编辑 | 编辑源代码]

可以定义专门的异常类来携带更多错误信息:

#include <iostream>
#include <string>

class MathError {
    std::string message;
    int errorCode;
public:
    MathError(const std::string& msg, int code) 
        : message(msg), errorCode(code) {}
    
    void print() const {
        std::cerr << "Error #" << errorCode << ": " << message << std::endl;
    }
};

double sqrt(double x) {
    if (x < 0) {
        throw MathError("Negative number", 1001);
    }
    // 实际平方根计算...
    return x; // 简化示例
}

int main() {
    try {
        sqrt(-1);
    } catch (const MathError& e) {
        e.print();
    }
    return 0;
}

输出:

Error #1001: Negative number

重新抛出异常[编辑 | 编辑源代码]

在catch块中可以使用空throw语句重新抛出当前异常:

try {
    // 可能抛出异常的代码
} catch (...) {
    // 记录错误但无法完全处理
    std::cerr << "Error logged" << std::endl;
    throw;  // 重新抛出原异常
}

异常规格说明(C++17前)[编辑 | 编辑源代码]

在C++17之前,可以使用异常规格说明(现已弃用):

void func() throw(std::runtime_error) {  // 只能抛出std::runtime_error
    // 函数实现
}

现代C++推荐使用noexcept说明符代替:

void func() noexcept {  // 保证不抛出任何异常
    // 函数实现
}

最佳实践[编辑 | 编辑源代码]

1. 优先使用标准异常类:如std::runtime_error, std::logic_error等 2. 按值抛出,按const引用捕获catch (const std::exception& e) 3. 避免抛出指针:可能导致内存泄漏 4. 保持异常对象轻量:异常处理不应成为性能瓶颈 5. 文档化异常行为:在函数文档中说明可能抛出的异常类型

数学公式示例[编辑 | 编辑源代码]

在科学计算中,throw常用于处理数学错误,如: 当计算贝塞尔函数时,参数x必须满足: x0 否则应抛出异常。

性能考虑[编辑 | 编辑源代码]

throw语句的执行成本比普通返回语句高得多,因为需要:

  • 构造异常对象
  • 栈展开(stack unwinding)
  • 查找匹配的catch块

仅在真正异常情况下使用throw,常规错误处理可考虑返回错误码等其他机制。

总结[编辑 | 编辑源代码]

throw语句是C++异常处理的基础,正确使用它可以:

  • 将错误处理代码与正常逻辑分离
  • 提供丰富的错误信息
  • 支持跨函数调用栈的错误传播

记住黄金法则:只对异常情况使用异常,不要将异常用于常规控制流。