【C++】异常处理 ⑤ ( 异常类型 | 传统 C 语言中的异常处理 | C++ 异常处理 - 抛出 int 类型异常 | 捕获异常类型 / 异常变量 | C++ 异常处理 - 抛出指针类型异常 )
  K1I6GvxBEuyy 2023年12月15日 21 0



文章目录

  • 一、传统异常处理
  • 1、C 语言中的异常处理
  • 2、代码示例 - 传统异常处理
  • 二、C++ 异常处理 - 抛出 int 类型异常
  • 1、C++ 异常处理
  • 2、C++ 异常接收方式
  • 3、捕获异常类型 / 异常变量
  • 4、代码示例 - 抛出 / 捕获 int 类型异常
  • 三、C++ 异常处理 - 抛出指针类型异常
  • 1、抛出 char* 字符串常量 类型异常
  • 2、代码示例 - 抛出 char* 字符串常量 类型异常








一、传统异常处理




1、C 语言中的异常处理



传统的 C 语言中 错误处理 , 是通过返回不同的 int 类型值进行的 , 如 :

  • 执行成功返回 0 ;
  • 情况一 执行失败 , 返回 1 ;
  • 情况二 执行失败 , 返回 2 ;


2、代码示例 - 传统异常处理



如下代码示例中 , 实现一个字符串拷贝功能 , 拷贝时可能遇到各种错误 , 如 : 源字符串 不符合要求 , 目的字符串不符合要求 , 拷贝过程出错等 ;

传统的 C 语言处理方式就是 : 返回 int 类型返回值 , 函数执行成功返回 0 , 不同的失败情况返回不同的返回值 ;



代码示例 :

#include "iostream"
using namespace std;

// 拷贝函数 
// 返回值 int 类型的错误码
int my_strcpy(char* to, char* from) {
	if (from == NULL)
	{
		// 源字符串出错
		return 1;
	}
	if (to == NULL)
	{
		// 目标字符串出错
		return 2;
	}
	
	// 拷贝前检查条件
	if (*from == 'J') 
	{
		// 源字符串不能是 J 开头的
		return 3;
	}

	// 逐个字节拷贝字符
	while (*from != '\0')
	{
		*to = *from;
		to++;
		from++;
	}
	*to = '\0';

	return 0;
}

int main() {

	// 字符串拷贝函数返回值
	int ret = 0;
	// 源字符串
	char str1[] = "Tom";
	// 目的字符串
	char str2[32] = {0};

	// 调用字符串拷贝函数
	ret = my_strcpy(str2, str1);

	// 根据不同的返回值进行不同的错误处理
	switch (ret)
	{
	case 0:
		cout << "拷贝成功 : str2 : " << str2 << endl;
		break;
	case 1:
		cout << "源字符串出错" << endl;
		break;
	case 2:
		cout << "目的字符串出错" << endl;
		break;
	case 3:
		cout << "拷贝过程出错" << endl;
		break;
	default:
		cout << "位置错误" << endl;
		break;
	}

	// 控制台暂停 , 按任意键继续向后执行
	system("pause");

	return 0;
};

执行结果 :

拷贝成功 : str2 : Tom
Press any key to continue . . .

【C++】异常处理 ⑤ ( 异常类型 | 传统 C 语言中的异常处理 | C++ 异常处理 - 抛出 int 类型异常 | 捕获异常类型 / 异常变量 | C++ 异常处理 - 抛出指针类型异常 )_异常处理






二、C++ 异常处理 - 抛出 int 类型异常




1、C++ 异常处理



在 C++ 中的 错误处理 可以不占用 返回值 位置 , 使用 异常处理 机制 , 在函数中 抛出 指定类型 的异常 进行处理 ;



2、C++ 异常接收方式



抛出异常后 , 捕获异常 , 接收异常有很多种方式 ;

  • 可以按照 普通类型
  • 可以按照 引用类型
  • 可以按照 指针类型


3、捕获异常类型 / 异常变量



在 catch 分支中 , 捕获异常时 , 可以写 异常变量 , 也可以不写 ;

  • 不写异常变量 : 只捕获异常类型 , 如 :
catch(int)

表示捕获 int 类型的异常 , 但是如果这么写了 , 只能拦截到异常 , 知道 抛出了一个 int 类型的异常 , 不能访问异常的具体内容 ;

  • 写异常变量 : 可以访问异常变量 , 知道抛出的异常值是多少 , 如 :
catch(int e)

通过上面的 变量 e , 可以知道抛出的异常的具体 int 数值是多少 ;



4、代码示例 - 抛出 / 捕获 int 类型异常



代码示例 :

#include "iostream"
using namespace std;

// 拷贝函数 
// 使用 throw 关键字抛出 int 类型的异常
void my_strcpy(char* to, char* from) throw(int) {
	if (from == NULL)
	{
		// 源字符串出错
		throw 1;
	}
	if (to == NULL)
	{
		// 目标字符串出错
		throw 2;
	}
	
	// 拷贝前检查条件
	if (*from == 'J') 
	{
		// 源字符串不能是 J 开头的
		throw 3;
	}

	// 逐个字节拷贝字符
	while (*from != '\0')
	{
		*to = *from;
		to++;
		from++;
	}
	*to = '\0';
}

int main() {

	// 源字符串
	char str1[] = "Tom";
	// 目的字符串
	char str2[32] = {0};

	try
	{
		// 调用字符串拷贝函数
		my_strcpy(str2, str1);

		cout << "拷贝成功 : str2 : " << str2 << endl;
	}
	// catch 分支中可以写 异常变量 , 也可以不写
	// 如果不写 , 则不能访问抛出的 异常对象
	catch (int e)
	{
		// 根据不同的返回值进行不同的错误处理
		switch (e)
		{
		case 1:
			cout << "源字符串出错" << endl;
			break;
		case 2:
			cout << "目的字符串出错" << endl;
			break;
		case 3:
			cout << "拷贝过程出错" << endl;
			break;
		default:
			cout << "位置错误" << endl;
			break;
		}
	}

	// 控制台暂停 , 按任意键继续向后执行
	system("pause");

	return 0;
};

执行结果 :

拷贝成功 : str2 : Tom
Press any key to continue . . .

【C++】异常处理 ⑤ ( 异常类型 | 传统 C 语言中的异常处理 | C++ 异常处理 - 抛出 int 类型异常 | 捕获异常类型 / 异常变量 | C++ 异常处理 - 抛出指针类型异常 )_异常类型_02






三、C++ 异常处理 - 抛出指针类型异常



抛出 / 捕获异常 , 有很多种方式 ;

  • 可以按照 普通类型
  • 可以按照 引用类型
  • 可以按照 指针类型


上一个章节 演示了 抛出 / 捕获 普通类型 异常 , 本章节介绍 抛出 / 捕获 引用类型 异常 ;



1、抛出 char* 字符串常量 类型异常



抛出 char* 字符串 指针类型异常 操作 , 与 抛出 普通变量类型的异常 操作相同 ;

字符串常量 存储在 符号表 中 , 因此可以在所有的函数之间传递 ;



抛出 / 捕获 异常 关键代码如下 :

  • 异常接口声明 : 注意 字符串常量 的类型为 const char* ;
void my_strcpy(char* to, char* from) throw(const char*)
  • 抛出 异常 : 直接抛出 字符串常量 , 不要分配内存 ;
throw "源字符串出错";
  • 捕获 异常 : 捕获 字符串常量 异常时 , 不要忘了使用 const 修饰指针指向的数据 ;
catch (const char* e)



2、代码示例 - 抛出 char* 字符串常量 类型异常



代码示例 :

#include "iostream"
using namespace std;

// 拷贝函数 
// 使用 throw 关键字抛出 字符串类型的异常
void my_strcpy(char* to, char* from) throw(const char*) {
	if (from == NULL)
	{
		// 源字符串出错
		throw "源字符串出错";
	}
	if (to == NULL)
	{
		// 目标字符串出错
		throw "目标字符串出错";
	}
	
	// 拷贝前检查条件
	if (*from == 'J') 
	{
		// 源字符串不能是 J 开头的
		throw "源字符串不能是 J 开头";
	}

	// 逐个字节拷贝字符
	while (*from != '\0')
	{
		*to = *from;
		to++;
		from++;
	}
	*to = '\0';
}

int main() {

	// 源字符串
	char str1[] = "Jerry";
	// 目的字符串
	char str2[32] = {0};

	try
	{
		// 调用字符串拷贝函数
		my_strcpy(str2, str1);

		cout << "拷贝成功 : str2 : " << str2 << endl;
	}
	// catch 分支中可以写 异常变量 , 也可以不写
	// 如果不写 , 则不能访问抛出的 异常对象
	catch (const char* e)
	{
		cout << "出现异常 : " << e << endl;
	}

	// 控制台暂停 , 按任意键继续向后执行
	system("pause");

	return 0;
};

执行结果 :

出现异常 : 源字符串不能是 J 开头
Press any key to continue . . .

【C++】异常处理 ⑤ ( 异常类型 | 传统 C 语言中的异常处理 | C++ 异常处理 - 抛出 int 类型异常 | 捕获异常类型 / 异常变量 | C++ 异常处理 - 抛出指针类型异常 )_字符串_03


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年12月15日 0

暂无评论

推荐阅读
  8Tw5Riv1mGFK   2024年05月01日   72   0   0 C++
  BYaHC1OPAeY4   2024年05月08日   53   0   0 C++
  yZdUbUDB8h5t   2024年05月05日   40   0   0 C++
  oXKBKZoQY2lx   2024年05月17日   51   0   0 C++
K1I6GvxBEuyy
作者其他文章 更多