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)!