C++ 异常处理:Try、Catch、throw 示例

什么是异常处理 C++?

异常处理 C++ 为您提供了处理意外情况(如运行时错误)的方法。因此,每当发生意外情况时,程序控制权就会转移到称为处理程序的特殊函数。

要捕获异常,请将某段代码置于异常检查之下。该段代码位于 try-catch 块内。

如果该段代码中出现异常情况,则会引发异常。接下来,异常处理程序将接管程序的控制权。

如果没有发生异常情况,代码将正常执行。处理程序将被忽略。

该 C++ 在本教程中,您将学习:

为什么要进行异常处理?

以下是使用异常处理的原因 C++:

  • 您将错误处理代码与正常代码分开。代码将更易读且更易于维护。
  • 函数可以处理它们选择的异常。即使函数抛出许多异常,它也只会处理其中的一些。调用者将处理未捕获的异常。

异常处理关键字

异常处理 C++ 围绕这三个关键词:

  • – 当程序遇到问题时,它会抛出异常。throw 关键字帮助程序执行抛出操作。
  • 捕捉– 程序使用异常处理程序来捕获异常。它被添加到程序中需要处理问题的部分。它是使用 catch 关键字完成的。
  • 尝试– try 块标识将激活某些异常的代码块。它后面应该跟一个或多个 catch 块。

假设一个代码块将引发异常。该方法将使用 try 和 catch 关键字来捕获该异常。try/catch 块应包围可能引发异常的代码。此类代码称为受保护代码。

句法

try/catch 采用以下语法:

try {
   // the protected code
} catch( Exception_Name exception1 ) {
   // catch block
} catch( Exception_Name exception2 ) {
   // catch block
} catch( Exception_Name exceptionN ) {
   // catch block
}
  • 虽然我们有一个 try 语句,但我们可以有许多 catch 语句。
  • ExceptionName 是要捕获的异常的名称。
  • exception1、exception2 和 exceptionN 是您定义的用于引用异常的名称。

例如1:

#include<iostream>
#include<vector>
using namespace std;

int main() {
	vector<int> vec;
	vec.push_back(0);	
	vec.push_back(1);	
	// access the third element, which doesn't exist
	try
	{
		vec.at(2);		
	}
	catch (exception& ex)
	{
		cout << "Exception occurred!" << endl;
	}
	return 0;
}

输出:

异常处理关键字

以下是代码截图:

异常处理关键字

代码说明:

  1. 在程序中包含 iostream 头文件以使用它 功能.
  2. 在程序中包含vector头文件即可使用其函数。
  3. 将程序中的 std 命名空间包含到其类中而不调用它。
  4. 调用 main() 函数。程序逻辑应添加到其主体内。
  5. 创建一个名为 vec 的向量来存储整数数据。
  6. 将元素 0 添加到名为 vec 的向量中。
  7. 将元素 1 添加到名为 vec 的向量中。
  8. 评论。它将被跳过 C++ 编译.
  9. 使用 try 语句来捕获异常。{ 标记 try/catch 块主体的开始。主体内添加的代码将成为受保护的代码。
  10. 尝试访问名为 vec 的向量中索引 2(第三个元素)处存储的元素。此元素不存在。
  11. try/catch 块主体结束。
  12. 捕获异常。返回的错误消息将存储在变量 ex 中。
  13. 如果捕获到异常,则在控制台上打印一些消息。
  14. 捕获块主体的末端。
  15. 程序执行成功后应该返回一个值。
  16. main() 函数体结束。

例如2:

#include <iostream>
using namespace std;
double zeroDivision(int x, int y) {

	if (y == 0) {
		throw "Division by Zero!";
	}
	return (x / y);
}

int main() {
	int a = 11;
	int b = 0;
	double c = 0;

	try {
		c = zeroDivision(a, b);
		cout << c << endl;
	}
	catch (const char* message) {
		cerr << message << endl;
	}
	return 0;
}

输出:

异常处理关键字

以下是代码截图:

异常处理关键字

代码说明:

  1. 在程序中包含iostream头文件以使用其功能。
  2. 将程序中的 std 命名空间包含到其类中而不调用它。
  3. 创建一个名为 zeroDivision 的函数,该函数接受两个整数参数 x 和 y。该函数应返回双精度结果。
  4. 使用 if 语句检查变量参数 y 的值是否为 0。{ 标记 if 语句主体的开始。
  5. 如果 y 为 0,则返回/抛出的消息。
  6. if 语句主体结束。
  7. zeroDivision 函数应该返回 x/y 的值。
  8. zeroDivision 函数体结束。
  9. 调用 main() 方法。{ 标记此方法的开始。
  10. 声明一个整型变量并赋值给它11。
  11. 声明一个整型变量 b 并赋值 0。
  12. 声明一个双精度变量 c 并赋值 0。
  13. 使用 try 语句来捕获异常。{ 标记 try/catch 块主体的开始。主体内添加的代码将成为受保护的代码。
  14. 调用 zeroDivision 函数并传递参数 a 和 b,即 11 和 0。此运算的结果将存储在变量 c 中。
  15. 在控制台上打印出变量c的值。
  16. try/catch 块主体结束。
  17. 捕获异常。返回的错误消息将存储在变量 message 中。
  18. 在控制台上打印出返回的错误信息。
  19. 捕获块主体的末端。
  20. 程序执行成功后应该返回一个值。
  21. main() 函数体结束。

C++ 标准异常

C++ 标准异常

C++ 附带了在以下位置定义的标准异常列表类。这些描述如下:

特殊课程 描述
std::exception 这是一个异常,也是所有标准 C++ 例外。
std::bad_alloc 此异常是由 new 关键字引发的。
std::bad_cast 这是 dynamic_cast 抛出的异常。
std::bad_exception 处理意外异常的有用设备 C++ 程式。
std::bad_typeid typeid 抛出的异常。
std::logic_error 理论上可以通过阅读代码来检测到这个异常。
std::domain_error 这是使用数学上无效的域后抛出的异常。
std::invalid_argument 因使用无效参数而引发的异常。
std::length_error 创建一个大的 std::string 后抛出异常。
std::超出范围 由 at 方法抛出。
std::runtime_error 这是一个无法通过读取代码检测到的异常。
std::overflow_error 发生数学溢出后会抛出此异常。
std::range_error 当您尝试存储超出范围的值时会抛出此异常。
std::underflow_error 发生数学下溢后抛出的异常。

用户定义的异常

这个 C++ std::exception 类允许我们定义可以作为异常抛出的对象。该类已在标头。该类为我们提供了一个名为 what 的虚拟成员函数。

此函数返回一个以 char * 类型结尾的空字符序列。我们可以在派生类中覆盖它以获得异常描述。

计费示例:

#include <iostream>
#include <exception>
using namespace std;

class newException : public exception
{
	virtual const char* what() const throw()
	{
		return "newException occurred";
	}
} newex;

int main() {

	try {
		throw newex;
		}
	catch (exception& ex) {
		cout << ex.what() << '\n';
	}
	return 0;	
}

输出:

用户定义的异常

以下是代码截图:

用户定义的异常

代码说明:

  1. 在我们的程序中包含 iostream 头文件。我们将使用它的功能而不会出现错误。
  2. 在我们的程序中包含异常头文件。我们将像没有错误一样使用它的功能。
  3. 在我们的程序中包含 std 命名空间,以便使用它的类而不调用它。
  4. 创建一个名为 newException 的新类。该类继承了 C++.
  5. 班级主体的开始。
  6. 覆盖异常头文件中定义的虚拟成员函数 what()。然后我们将描述我们自己的异常,即新异常。
  7. 开始新异常的定义。
  8. 如果捕获到新的异常则返回的消息。
  9. 新异常的定义结束。
  10. newException 类主体结束。newex 是用于捕获新异常的名称,之后将调用 newException。
  11. 调用 main() 函数。程序逻辑应添加到其主体内。{ 标记其主体的开始。
  12. 使用 try 语句来标记需要标记异常的代码。{ 标记 try/catch 块主体的开始。被它包围的代码将受到保护。
  13. 如果捕获到,则抛出新的异常。
  14. 尝试主体结束。
  15. 使用catch语句捕获异常,异常错误信息会保存在变量ex中。
  16. 在控制台上打印异常错误信息。
  17. catch 语句主体结束。
  18. 如果程序执行成功,它应该返回一个值。
  19. main() 函数体结束。

结语

  • 使用异常处理 C++,您可以处理运行时错误。
  • 运行时错误是在程序执行过程中发生的错误。
  • 异常处理可帮助您处理程序中的任何意外情况。
  • 当意外情况发生时,程序控制权将转移给处理程序。
  • 为了捕获异常,您需要将一段代码放在 try-catch 块下。
  • throw 关键字帮助程序抛出异常,帮助程序处理问题。
  • try 关键字有助于识别将激活某些异常的代码块。
  • 我们可以覆盖异常头文件的what()函数来定义我们的异常。