C++ 入门第27天:异常处理详细讲解
往期回顾:
C++ 入门第24天:C++11 多线程基础-CSDN博客
C++ 入门第25天:线程池(Thread Pool)基础-CSDN博客
C++ 入门第26天:文件与流操作基础-CSDN博客
C++ 入门第27天:异常处理详细讲解
前言
在 C++ 开发中,异常处理是一种重要的错误处理机制,它能够让程序在遇到错误时优雅地处理,而不是直接崩溃。C++ 提供了 try
-catch
-throw
语法来捕获和处理异常。
今天,我们将学习:
(1)异常的基本概念
(2)如何抛出和捕获异常
(3)标准异常类 std::exception
(4)自定义异常
1. 什么是异常?
异常(Exception) 是指程序运行时发生的错误,例如:
1、除零错误
2、访问越界
3、内存分配失败
4、文件打开失败
C++ 提供了 异常机制,允许程序在错误发生时抛出异常,并由调用者捕获并处理。
2. try
-catch
-throw
语法
2.1 基本用法
#include <iostream>
using namespace std;
int main() {
try {
throw "发生异常!"; // 抛出异常
} catch (const char* msg) { // 捕获异常
cout << "捕获异常:" << msg << endl;
}
return 0;
}
运行结果:
捕获异常:发生异常!
其中主要是三个关键字的使用:
throw
关键字用于抛出异常。
try
代码块包裹可能发生异常的代码。
catch
代码块用于捕获并处理异常。
3. 抛出和捕获不同类型的异常
C++ 允许抛出各种类型的异常,包括 int
、double
、string
等。
#include <iostream>
using namespace std;
void testException(int type) {
if (type == 1)
throw 404; // 抛出整数
else if (type == 2)
throw 3.14; // 抛出浮点数
else if (type == 3)
throw string("异常信息!"); // 抛出字符串
}
int main() {
try {
testException(3);
} catch (int e) {
cout << "捕获整数异常:" << e << endl;
} catch (double e) {
cout << "捕获浮点数异常:" << e << endl;
} catch (string e) {
cout << "捕获字符串异常:" << e << endl;
}
return 0;
}
运行结果:
捕获字符串异常:异常信息!
注意:
catch
语句的顺序很重要,应从具体类型到通用类型(catch (...)
)。- 如果没有匹配的
catch
语句,程序会终止。
4. 使用 std::exception
进行异常处理
C++ 标准库提供了 std::exception
及其子类,用于处理不同类型的异常:
4.1 std::exception
基础用法
#include <iostream>
#include <exception>
using namespace std;
int main() {
try {
throw exception(); // 抛出标准异常
} catch (const exception& e) {
cout << "捕获标准异常:" << e.what() << endl;
}
return 0;
}
注意,其中e.what()
返回异常信息,默认是 "std::exception"
。
4.2 std::runtime_error
和 std::logic_error
C++ 提供了两个常见的异常类型:
(1)runtime_error
:用于运行时错误(如除零、文件未找到)。
(2)logic_error
:用于逻辑错误(如数组越界)。
#include <iostream>
#include <stdexcept>
using namespace std;
int main() {
try {
throw runtime_error("运行时错误!");
} catch (const runtime_error& e) {
cout << "捕获 runtime_error:" << e.what() << endl;
}
return 0;
}
运行结果:
捕获 runtime_error:运行时错误!
5. 自定义异常类
如果标准异常不能满足需求,可以定义自己的异常类,继承 std::exception
。
#include <iostream>
#include <exception>
using namespace std;
// 自定义异常类
class MyException : public exception {
public:
const char* what() const noexcept override {
return "自定义异常发生!";
}
};
int main() {
try {
throw MyException();
} catch (const MyException& e) {
cout << "捕获异常:" << e.what() << endl;
}
return 0;
}
运行结果:
捕获异常:自定义异常发生!
自定义异常类要注意两个要点:
(1)继承 std::exception
并重写 what()
方法。
(2)noexcept
关键字表示 what()
不会抛出异常。
6. catch(...)
捕获所有异常
如果不确定会抛出什么类型的异常,可以使用 catch(...)
捕获所有异常。
#include <iostream>
using namespace std;
int main() {
try {
throw 3.14; // 抛出一个 double 类型的异常
} catch (...) {
cout << "捕获了未知异常!" << endl;
}
return 0;
}
运行结果:
捕获了未知异常!
catch(...)
通常放在最后,以捕获所有未处理的异常。
7. noexcept
关键字
C++11 引入了 noexcept
,用于标识一个函数不会抛出异常。
#include <iostream>
using namespace std;
void safeFunction() noexcept {
cout << "这个函数不会抛出异常" << endl;
}
int main() {
safeFunction();
return 0;
}
使用noexcept的
作用是,一方面告诉编译器该函数不会抛出异常,可以优化性能。另一方面,如果 noexcept
函数抛出异常,程序会调用 std::terminate()
终止。
8. 总结
以上就是 C++ 11 中异常处理操作的基础详细知识点了。从异常的基本概念,到try
-catch
-throw
语句的使用方法,再到标准异常 std::exception
及其子类,以及我们还可以自定义异常,使用 catch(...)
捕获所有异常,还有noexcept
关键字。异常处理是编写健壮 C++ 程序的关键技巧。合理使用异常,可以提高程序的稳定性,并让错误处理更加清晰。
都看到这里了,点个赞再走呗朋友~
加油吧,预祝大家变得更强!