自学内容网 自学内容网

C++异常_C++回顾

用法

C++中的异常处理是一种强大的错误处理机制,它允许在运行时检测和处理错误或异常情况。C++提供了try、catch和throw三个关键字来处理异常。

下面是一个简单的C++异常使用示例:

#include <iostream>  
#include <stdexcept>  
  
// 一个简单的函数,可能抛出异常  
void divide(int a, int b) {  
    if (b == 0) {  
        throw std::invalid_argument("除数不能为0");  
    }  
    std::cout << "结果是: " << a / b << std::endl;  
}  
  
int main() {  
    try {  
        divide(10, 0);  // 这里会抛出异常  
    } catch (const std::invalid_argument& e) {  
        std::cerr << "捕获到异常: " << e.what() << std::endl;  
    }  
  
    try {  
        divide(10, 2);  // 这里不会抛出异常  
    } catch (const std::exception& e) {  
        std::cerr << "捕获到异常: " << e.what() << std::endl;  
    }  
  
    return 0;  
}

在这个示例中,divide函数可能抛出一个std::invalid_argument异常,当除数为0时。在main函数中,我们使用try块来调用divide函数,并在catch块中捕获并处理异常。

当我们调用divide(10, 0)时,会抛出异常,并被catch块捕获,然后输出异常信息。当我们调用divide(10, 2)时,不会抛出异常,因此catch块不会执行。

注意,catch块可以捕获不同类型的异常,但通常建议尽可能具体地指定要捕获的异常类型,以便更好地处理不同类型的异常。

自定义异常

在C++中,可以通过创建一个新的类来自定义异常。这个新类通常继承自std::exception类或其派生类,这样可以利用std::exception类提供的功能,包括what()成员函数,它返回一个描述异常的字符串。

#include <string>  
#include <exception>  
  
// 自定义的异常类,继承自 std::exception  
class MyCustomException : public std::exception {  
public:  
    // 构造函数,接收一个描述异常的字符串  
    explicit MyCustomException(const std::string& message) : message_(message) {}  
  
    // 实现 std::exception 的 what() 函数,返回异常描述  
    const char* what() const throw() {  
        return message_.c_str();  
    }  
  
private:  
    std::string message_; // 存储异常信息的成员变量  
};  
  
// 一个可能抛出自定义异常的函数  
void doSomething() {  
    // ... 一些代码 ...  
      
    // 在某种条件下抛出自定义异常  
    throw MyCustomException("这是一个自定义异常");  
}  
  
int main() {  
    try {  
        // 调用可能抛出异常的函数  
        doSomething();  
    } catch (const MyCustomException& e) {  
        // 捕获自定义异常并处理  
        std::cerr << "捕获到自定义异常: " << e.what() << std::endl;  
    } catch (const std::exception& e) {  
        // 捕获其他标准异常  
        std::cerr << "捕获到标准异常: " << e.what() << std::endl;  
    }  
  
    return 0;  
}

异常的优缺点

优点

异常对象定义好了,相比错误码的方式可以清晰准确地展示出错误的各种信息,甚至可以包含栈堆调用的信息,这样可以帮助更好地定位程序的BUG。

返回错误码的传统方式有个很大的问题就是,在函数调用链中,深层的函数返回了错误,那么我们得层层返回错误,最外层才能拿到错误。如果是异常体系,抛出的异常会直接跳到catch捕获的地方。

很多的第三方库都包含异常,比如boost、gtest、gmock等等常用的库,那么我们使用它们也需要使用异常。

部分函数使用异常更好处理,比如构造函数没有返回值,不方便使用错误码方式处理。比如T& operator这样的函数,如果pos越界了只能使用异常或者终止程序处理,没办法通过返回值表示错误。

缺点

异常会导致程序的执行流乱跳,并且非常混乱,并且是运行时出错抛异常就会乱跳。这会导致我们跟踪调试时以及分析程序时比较困难。

异常会有一些性能的开销。当然在现代硬件速度很快的情况下这个开销可以忽略不计。

C++没有垃圾回收机制,资源需要自己管理。有了异常非常容易导致内存泄漏、死锁等异常安全问题。这个需要RAII来处理资源的管理问题,学习成本较高。

C++标准库的异常体系定义得不好,导致大家各自定义的异常体系,非常混乱。

异常尽量规范使用,否则后果不堪设想随意抛异常,外层捕获的用户苦不堪言。所以异常规范有两点:一、抛出异常类型都继承自一个基类。二、函数是否抛异常、抛什么异常,都使用func(){throw();}的方式规范化。

总结:异常总体而言,利大于弊,所以工程中我们还是鼓励使用异常。此外OO语言基本都是使用异常处理错误,这也是大势所趋。


原文地址:https://blog.csdn.net/m0_60464690/article/details/136316374

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!