博客总结 :
代码语言:javascript复制// 1. 不会抛出异常
void fun() throw();
// 2. 可能会抛出 int 类型的异常
void fun() throw(int);
// 3. 可能会抛出 int 或 double 类型的异常
void fun() throw(int, double);
// 4. 抛出任意类型异常
void fun() throw(...);
// 5. 抛出任意类型异常
void fun();
一、异常接口声明
1、异常接口引入
在 C 中 , 异常可以使用 任意 类型 进行表示 , 但是 一般情况下 使用 派生自 标准异常类 std::exception 的 自定义异常类 来表示 异常 ;
" 异常接口 " 用于表示 在 函数中 要抛出的 异常类型 ;
为了 加强 程序的 可读性 , 可维护性 , 推荐将 函数 可能会抛出异常 写入到 函数的 异常接口 中,即 在 函数中国年 列出所有可能抛出的异常类型 ;
2、异常接口语法
在 C 语言中 , 异常接口 的声明使用 throw() 关键字 , 用于指定函数要抛出的异常类型 ;
异常接口语法如下 :
代码语言:javascript复制函数返回值 函数名(函数参数列表) throw (异常类型1, 异常类型2, ..., 异常类型n)
3、抛出一种类型的异常
抛出一种类型的异常 : 在 void fun() 函数中 , 可能会抛出 int 类型的异常 , 可以使用如下异常接口声明 ;
代码语言:javascript复制// 可能会抛出 int 类型的异常
void fun() throw(int) {
// 函数体
}
代码示例 :
代码语言:javascript复制#include "iostream"
using namespace std;
// 1. 在 函数 中 抛出异常
// 异常接口 : 只允许抛出 char 类型异常
void fun() throw(char) {
cout << "开始抛出 char 类型 异常 " << endl;
// 抛出一个 char 类型的异常
throw 'A';
}
int main() {
// 2. 捕获并处理异常
try
{
// 调用可能产生异常的函数
fun();
}
// 捕获一切未知类型的异常
catch ( ... )
{
cout << "捕获到未知类型异常 ... "<< endl;
}
// 控制台暂停 , 按任意键继续向后执行
system("pause");
return 0;
};
执行结果 :
4、抛出多种类型的异常
抛出多种类型的异常 : 在 void fun() 函数中 , 可能会抛出多个类型的异常 , 可以使用如下异常接口声明 , 多个异常类型之间使用逗号隔开 ;
代码语言:javascript复制// 可能会抛出 int , char , double 类型的异常
void fun() throw(int, char, double) {
// 函数体
}
代码示例 :
代码语言:javascript复制#include "iostream"
using namespace std;
// 1. 在 函数 中 抛出异常
// 异常接口 : 只允许抛出 double, int, char 类型异常
void fun() throw(double, int, char) {
cout << "开始抛出 char 类型 异常 " << endl;
// 抛出一个 char 类型的异常
throw 'A';
}
int main() {
// 2. 捕获并处理异常
try
{
// 调用可能产生异常的函数
fun();
}
// 捕获一切未知类型的异常
catch ( ... )
{
cout << "捕获到未知类型异常 ... "<< endl;
}
// 控制台暂停 , 按任意键继续向后执行
system("pause");
return 0;
};
执行结果 :
5、抛出任何类型异常 - 不声明异常接口 / 声明 throw(…)
可抛出任何类型异常 的 函数 , 有如下两种声明方式 :
- 不声明异常接口 : 在 函数 中 , 如果 不声明 异常接口 , 默认可以抛出任何类型的异常 ;
// 1. 在 函数 中 抛出异常
void fun() {
cout << "开始抛出 char 类型 异常 " << endl;
// 抛出一个 char 类型的异常
throw 'A';
}
- 声明 throw(…) 异常接口 : 如果 函数的 异常接口 声明为 throw(…) , 则可以抛出任意类型的异常 ;
// 在 函数 中 抛出任意类型异常
void fun() throw(...) {
cout << "开始抛出 char 类型 异常 " << endl;
// 抛出一个 char 类型的异常
throw 'A';
}
6、不能抛出任何类型异常 - 声明 throw()
如果禁止函数抛出异常 , 则声明异常接口为 throw() , 如果 在 函数中有抛出异常的行为 , 在编译时会发出警告 ;
代码语言:javascript复制// 不允许抛出异常
void fun() throw() {
// 函数体
}
如果抛出了异常 , 会报错 : " 警告 C4297 “fun”: 假定函数不引发异常,但确实发生了 "
代码语言:javascript复制严重性 代码 说明 项目 文件 行 禁止显示状态
警告 C4297 “fun”: 假定函数不引发异常,但确实发生了 HelloWorld D: 02_Project 06_Visual_StudioHelloWorldHelloWorldTest.cpp 11
代码示例 :
代码语言:javascript复制#include "iostream"
using namespace std;
// 1. 在 函数 中 抛出异常
// 异常接口 : 不允许抛出异常
void fun() throw() {
cout << "开始抛出 char 类型 异常 " << endl;
// 抛出一个 char 类型的异常
throw 'A';
}
int main() {
// 2. 捕获并处理异常
try
{
// 调用可能产生异常的函数
fun();
}
// 捕获一切未知类型的异常
catch ( ... )
{
cout << "捕获到未知类型异常 ... "<< endl;
}
// 控制台暂停 , 按任意键继续向后执行
system("pause");
return 0;
};
编译警告 :
代码语言:javascript复制已启动生成…
1>------ 已启动生成: 项目: HelloWorld, 配置: Debug Win32 ------
1>Test.cpp
1>D: 02_Project 06_Visual_StudioHelloWorldHelloWorldTest.cpp(11,1): warning C4297: “fun”: 假定函数不引发异常,但确实发生了
1>D: 02_Project 06_Visual_StudioHelloWorldHelloWorldTest.cpp(11,1): message : 在函数上指定了 __declspec(nothrow)、throw()、noexcept(true)或 noexcept
1>HelloWorld.vcxproj -> D: 02_Project 06_Visual_StudioHelloWorldHelloWorldDebugHelloWorld.exe
1>已完成生成项目“HelloWorld.vcxproj”的操作。
========== 生成: 成功 1 个,失败 0 个,最新 0 个,跳过 0 个 ==========
执行结果 :
7、抛出异常类型错误
抛出异常类型错误 : 如果一个函数抛出了它的异常接口声明所不允许抛出的异常 , 会调用 unexpected 函数 , 该函数会调用 terminate 函数 中止程序 , 程序崩溃 ;
下面的 函数中 , 只能抛出 int , double 类型的异常 , 结果在 函数体中 抛出了 char 类型的异常 , 程序会发出警告 ;
代码语言:javascript复制// 1. 在 函数 中 抛出异常
void fun() throw( double ) {
cout << "开始抛出 char 类型 异常 " << endl;
// 抛出一个 char 类型的异常
throw 'A';
}
警告内容 : 0x75D5D8A2 处(位于 HelloWorld.exe 中)引发的异常: Microsoft C 异常: char,位于内存位置 0x0116F607 处。
代码示例 :
代码语言:javascript复制#include "iostream"
using namespace std;
// 1. 在 函数 中 抛出异常
// 异常接口 : 只允许抛出 double 类型异常
void fun() throw( double ) {
cout << "开始抛出 char 类型 异常 " << endl;
// 抛出一个 char 类型的异常
throw 'A';
}
int main() {
// 2. 捕获并处理异常
try
{
// 调用可能产生异常的函数
fun();
}
// 捕获一切未知类型的异常
catch ( ... )
{
cout << "捕获到未知类型异常 ... "<< endl;
}
// 控制台暂停 , 按任意键继续向后执行
system("pause");
return 0;
};
编译警告 :
代码语言:javascript复制已启动生成…
1>------ 已启动生成: 项目: HelloWorld, 配置: Debug Win32 ------
1>Test.cpp
1>D: 02_Project 06_Visual_StudioHelloWorldHelloWorldTest.cpp(6,24): warning C4290: 忽略 C 异常规范,但指示函数不是 __declspec(nothrow)
1>HelloWorld.vcxproj -> D: 02_Project 06_Visual_StudioHelloWorldHelloWorldDebugHelloWorld.exe
1>已完成生成项目“HelloWorld.vcxproj”的操作。
========== 生成: 成功 1 个,失败 0 个,最新 0 个,跳过 0 个 ==========
执行结果 :
代码语言:javascript复制开始抛出 char 类型 异常
捕获到未知类型异常 ...
Press any key to continue . . .
警告信息 :
代码语言:javascript复制0x75D5D8A2 处(位于 HelloWorld.exe 中)引发的异常: Microsoft C 异常: char,位于内存位置 0x0116F607 处。