1、常见异常错误:
2、语法错误:由于语法等问题导致在程序编译过程中发生错误,无法生成可执行文件。又称为编译错误,
3、运行错误:应为代码逻辑或其他原因导致代码不能正常执行,出现终止或死机等其他现象,且此类问题存在较为隐蔽,较难察觉,例如:出现除数为0,内存空间不足等等。
故为减少因此类问题而产生的问题引入异常处理方法。
4、处理机制:在大型程序开发过程中为减少因函数自身进行异常处理而造成的复杂性,c++采用向上 逐级询问的方式来解决异常,如本函数不能处理异常,则返回上一层及调用本函数的函数查询是否存在处理语句,如此直至找到为止,
5、组成:try(尝试)、catch(捕捉)、throw(抛出)
6、处理过程:将要检查的语句放在try中,由throw语句抛出异常信号,由catch语句接收异常信号,并进行相应的异常处理。
举一个简单的例子:
#include<iostream>
using namespace std;
//以输出成绩为例 如果成绩在0-100之间 就输出成绩 否则输出错误 将功能封装在函数中
int main()
{
void showscore(); //函数声明
//调用函数
try
{
while (1) //只要输入成绩未发生异常,则一直执行下去,
{
showscore();
}
//当出现我们假设的异常时,程序从showscore函数中寻找catch未果,
//在本级函数中寻找,跳出while循环
}
catch (int) //捕捉异常信号,如果符合条件则进行处理
{
cout << "错误" << endl;
}
system("pause");
return 0;
}
//实现输出函数
void showscore()
{
cout << "请输入你要输出的成绩:" << endl;
int a;
cin >> a;
if (a < 0 || a>100) throw a;//此时发生我们假设的异常情况,程序在本函数中寻找catch处理,未找到,返回上一层调用中寻找,
cout << "成绩为:" << a << endl;
}
运行结果;
z
注意:
在使用异常处理时,try 和 catch 成对使用,{}不能够省略,只有一条语句也不可以。
catch在捕捉中可以加上变量名,进行参数传递。
catch(...) 可以捕捉任何类型的异常变量,若在括号中出现的变量类型,则只可以捕捉类型范围内的变量。若空,则不会接收任何异常变量,在多级查询catch中,异常信号不符合则不处理。
throw:在函数声明中可以确定抛出的异常变量类型 未指定则不能抛出。
6、多层嵌套调用过程中的异常处理
#include<iostream>
using namespace std;
void test03() //嵌套调用 第三层调用 假设在其中可能发生异常
{
cout << "test03开始" << endl;
try
{
while (1) //发生异常则退出循环寻找异常处理语句
{
cout << "请输入你要输出的成绩:" << endl;
int a;
cin >> a;
//自定义一个异常变量
int b = 1;
if (a < 0 || a>100)
{
throw b;
}
cout << a << endl;
}
}
catch (double)
{
cout << "test03中的异常处理" << endl;
}
cout << "test03结束" << endl;
}
void test02()
{
cout << "test02开始" << endl;
try
{
test03(); //调用tese03
}
catch (int)
{
cout << "test02的异常处理" << endl;
}
cout << "test02结束" << endl;
}
void test01()
{
cout << "test01开始" << endl;
try {
test02(); //调用test02
}
catch(...) { //接收处理任何异常信号
cout << "test01的异常处理" << endl;
}
cout << "test01结束" << endl;
}
int main()
{
cout << "main函数开始" << endl;
try
{
test01(); //调用test01
}
catch (int) //与test02中的捕获异常信号相同,但只处理一次,即先捕获先处理
{
cout << "main函数中的异常处理" << endl;
}
cout << "main函数运行结束" << endl;
system("pause");
return 0;
}
简单的测试结果
注意:在多层嵌套调用过程中的异常处理,逐级寻找与之匹配的异常处理,但只要找到一个就会进行相应处理,结束后继续执行后面的命令,不在进行异常处理。
7、在异常处理中处理析构函数
在使用自定义变量时,如果发生异常,由于已经构造对象,程序在发生异常错误时会调用析构函数来释放对象的内存空间,然后寻找与之匹配的异常处理。测试代码如下:
#include<iostream>
using namespace std;
#include<string>
//自定义数据类型
class Person
{
public:
//构造函数
Person(string a,int b);
//析构函数
~Person();
//获得属性
void get();
private:
//属性
string name;
int age;
};
//类外实现函数
Person::Person(string a,int b)
{
cout <<a<< "构造函数的调用" << endl;
this->name = a;
age = b;
}
void Person::get()
{
if (age > 100)
{
throw name;
}
else
{
cout << this->name << " " << this->age << endl;
}
}
Person::~Person()
{
cout<<this->name<< "析构函数的调用" << endl;
}
//测试函数的实现
void test()
{
Person p("张三",22);
p.get();
Person p1("李四", 233);
p1.get();
}
int main()
{
try {
test();
}
catch(string c) {
cout << c << "年龄错误!" << endl;
}
system("pause");
return 0;
}
注意:在本次测试中,catch语句中的接收异常信号来自李四的抛出信号,利用其可进行参数传递。