程序异常抛出和处理
异常处理分类
方法 | 功能 | 用法 |
---|---|---|
noexcept修饰符(拓展:noexcept也可作为运算符)(C++11) | debug模式下发现异常终止程序 | 修饰一定不会错的函数 |
throw函数 | 主动抛出异常 | 放在try中抛出异常 |
assert函数 | debug模式下程序运行中发现逻辑为假时终止程序 | 处理程序运行中逻辑判断程序是否继续运行 |
static_assert函数(C++11) | debug模式下程序编译中发现逻辑为假时终止程序编译 | 在编译层面就可以进行逻辑判断,从而终止 |
exit函数 | 执行终止程序运行 |
注意:上述的几种方法中,assert
、static_assert
、noexcept
是只有在程序为debug
下才会让程序直接退出,但是在Release
下不会让程序退出。
noexcept
作为修饰词时,只有在debug下才会终止程序
概念
noexcept属于C++11起的新特性。
主要作用
- 修饰不会出错函数,如果出错则会终止程序抛出异常
- 作为运算符判断该函数有没有被noexcept修饰,即判断该函数会不会抛出异常
语法
//作为修饰词
void func() noexcept{ 表达式 }
//作为运算符
noexcept(func())
范例1:作为修饰词
作为修饰词时,debug下抛错,Relearese下不会报错
void func14(void) noexcept
{
cout << "测试 noexcept" << endl;
int arr[3]{ 0,1,2 };
arr[3] = 4; //这里内存越界,debug下抛错,Relearese下不会报错
}
范例2:作为运算符时
可以在debug和Relearese都可以使用,输出该函数会不会抛出异常(这个函数有没有被修饰)。
void func15_1()noexcept { cout << "func15_1" << endl; }
void func15_2() { cout << "func15_2" << endl; }
void func15() {
cout << noexcept(func15_1()) << endl; //有被noexcept修饰,返回1
cout << noexcept(func15_2()) << endl; //没有被noexcept修饰,返回0
}
throw
语法
try{
表达式……
throw value;
}
catch(valueType v){ //抛出异常为valueType类型时触发
表达式
}
catch(...){ //抛出所有异常时触发
表达式
}
示例1:异常捕获的常用方式
void func12(void)
{
std::stoll("error");
}
void func13() noexcept{
try
{
func12();
}
catch (...)
{
std::cout << "捕获错误" << std::endl;
}
}
示例2:根据错误类型执行不同的表达式
assert断言
只有在debug
下才会终止程序,Release
模式下忽略
语法
assert(表达式)
用途:用于逻辑判断是否抛出错误
范例1: debug下使用
void func17() {
//表达式为true的情况下
assert(true);
std::cout << "assert(true)通过" << std::endl;
//表达式为false的情况下
assert(false);
std::cout << "assert(false)通过" << std::endl;
}
范例2: Release下使用
同范例1中的代码,在Relsase下直接通过,不会抛出异常
优缺点
优点: 在函数的()可以是表达式
缺点:在debug下运行中如果多次调用会影响程序稳定性,会有很多额外开销。
static_assert静态断言
概念
C++11中的新特性,和assert的区别在于,static_assert
是在编译阶段运行。并且不能再传入带有变量的表达式,而你只能传常量表达式。
语法
static_assert(常量表达式, 提示字符串 )
用途:用于逻辑判断是否抛出错误
可以判断程序是32位还是64位。
void func18() {
static_assert(sizeof(int *)==4, "This is not a 32-bit program");
static_assert(sizeof(int *)==8, "This is not a 64-bit program"); //编译报错
}
exit函数
exit()函数比较常见,即在代码需要退出处加入此函数即可。
在程序退出前会调用退出处理函数 ,清理I/O缓存