【C++】异常处理 ⑤ ( 异常类型 | 传统 C 语言中的异常处理 | C++ 异常处理 - 抛出 int 类型异常 | 捕获异常类型 / 异常变量 | C++ 异常处理 - 抛出指针类型异常 )
文章目录
- 一、传统异常处理
- 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++ 异常处理 - 抛出 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++ 异常处理 - 抛出指针类型异常
抛出 / 捕获异常 , 有很多种方式 ;
- 可以按照 普通类型 抛出 / 捕获异常 ,
- 可以按照 引用类型 抛出 / 捕获异常 ,
- 可以按照 指针类型 抛出 / 捕获异常 ;
上一个章节 演示了 抛出 / 捕获 普通类型 异常 , 本章节介绍 抛出 / 捕获 引用类型 异常 ;
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 . . .
还没有评论,来说两句吧...