[C++] 异常处理机制及使用案例

什么是C++异常处理?

C++ 异常处理是一种机制,用于在程序运行过程中处理可能发生的错误或异常情况。当发生异常时,程序会跳出当前的执行流程,并查找能够处理该异常的代码块,执行相应的处理逻辑,从而避免程序崩溃或产生未定义行为。

异常可以是由系统抛出的(如内存分配失败)或由程序员主动抛出的(如检测到输入错误)。C++ 中的异常处理机制主要包括以下几个部分:

  1. 异常的抛出:使用 throw 关键字抛出异常对象。

  2. 异常的捕获:使用 try-catch 块捕获异常,并执行相应的处理逻辑。

  3. 异常的处理:在 catch 块中,可以对捕获到的异常进行处理,包括输出异常信息、记录日志、重新抛出异常或返回默认值等。

  4. 异常的传递:如果异常没有被捕获,它会在调用栈中继续向上抛出,直到遇到能够处理异常的代码块。

异常处理能够增强程序的健壮性和可靠性,使得程序能够更好地应对异常情况并进行相应的处理。

C++ 异常处理的案例

以下是一些使用 C++ 异常处理的案例:

数组越界异常处理

#include <iostream>
#include <stdexcept>

int main() {
    int arr[3] = {1, 2, 3};
    try {
        int val = arr[5];
    } catch(const std::out_of_range& e) {
        std::cout << "数组越界异常:" << e.what() << std::endl;
    }
    return 0;
}

文件打开异常处理

#include <iostream>
#include <fstream>
#include <stdexcept>

int main() {
    std::ifstream file;
    try {
        file.open("nonexistent.txt");
        if (!file.is_open()) {
            throw std::runtime_error("文件打开失败");
        }
        // 其他文件操作
        file.close();
    } catch(const std::exception& e) {
        std::cout << "异常:" << e.what() << std::endl;
    }
    return 0;
}

自定义异常类

#include <iostream>
#include <stdexcept>

class MyException : public std::exception {
public:
    MyException(const char* message) : m_message(message) {}
    virtual const char* what() const noexcept {
        return m_message;
    }
private:
    const char* m_message;
};

int divide(int numerator, int denominator) {
    if (denominator == 0) {
        throw MyException("除数不能为零");
    }
    return numerator / denominator;
}

int main() {
    try {
        int result = divide(10, 0);
    } catch(const MyException& e) {
        std::cout << "自定义异常:" << e.what() << std::endl;
    }
    return 0;
}

这些示例展示了如何使用 C++ 异常处理来处理各种异常情况,保护代码免受错误的影响,并提供适当的错误信息。

stdexcept 标准库

stdexcept 是 C++ 标准库中的头文件,其中定义了一些常见的异常类。它提供了一组用于常见异常类型的类,这些异常类是从 std::exception 类派生而来的。

以下是 stdexcept 头文件中定义的异常类和使用案例:

std::logic_error 异常类

  • std::logic_error 是一个基类,用于派生针对逻辑错误的异常类,如 std::invalid_argument 和 std::length_error

  • 示例:

    #include <iostream>
    #include <stdexcept>
    
    int main() {
        try {
            throw std::logic_error("逻辑错误");
        } catch(const std::logic_error& e) {
            std::cout << "逻辑错误异常:" << e.what() << std::endl;
        }
        return 0;
    }
    
    

std::invalid_argument 异常类

  • std::invalid_argument 表示传递给函数的参数无效。

  • 示例:

    #include <iostream>
    #include <stdexcept>
    
    int divide(int numerator, int denominator) {
        if (denominator == 0) {
            throw std::invalid_argument("除数不能为零");
        }
        return numerator / denominator;
    }
    
    int main() {
        try {
            int result = divide(10, 0);
        } catch(const std::invalid_argument& e) {
            std::cout << "无效参数异常:" << e.what() << std::endl;
        }
        return 0;
    }

std::length_error 异常类

  • std::length_error 表示长度错误,例如字符串长度超出限制。

  • 示例:

    #include <iostream>
    #include <stdexcept>
    
    int main() {
        try {
            std::string str(1000000000, 'a');  // 创建一个长度为 1,000,000,000 的字符串
        } catch(const std::length_error& e) {
            std::cout << "长度错误异常:" << e.what() << std::endl;
        }
        return 0;
    }

std::out_of_range 异常类

  • std::out_of_range 表示索引超出范围,例如数组越界或迭代器越界。

  • 示例:

    #include <iostream>
    #include <stdexcept>
    
    int main() {
        try {
            std::vector<int> vec = {1, 2, 3};
            int value = vec.at(5);  // 索引超出范围
        } catch(const std::out_of_range& e) {
            std::cout << "索引超出范围异常:" << e.what() << std::endl;
        }
        return 0;
    }

通过使用 stdexcept 中定义的异常类,可以更方便地创建和处理常见的异常情况,提供有用的错误信息,并帮助代码更健壮地处理异常。

猜你喜欢

转载自blog.csdn.net/u011775793/article/details/136203765