注意点都在程序中有体现,也做出了明确解释。
1:异常的语法
#include <iostream>
using namespace std;
void func()
{
throw "发生异常"; //抛出异常
}
int main()
{
try
{
func(); //可能发生错误的语句 注意:要将可能发生异常的语句放到try{}中,否则无法捕获异常
}
catch(const char* &obj)
{
cout << obj << endl; //异常处理语句 注意:捕获到异常后的处理语句放到catch{}语句块中
}
return 0;
}
二:异常的使用说明
#include <iostream>
using namespace std;
void fun1()
{
cout << "fun1函数被调用" << endl;
throw "fun1 函数发生错误"; //抛出一个异常
cout << "fun1函数调用结束" << endl;
}
void fun2()
{
cout << "fun2 函数被调用" << endl;
fun1();
cout << "fun2函数调用结束" << endl;
}
void fun3()
{
cout << "fun3函数被调用" << endl;
try
{
fun2(); //可能发生异常的语句
}
catch(const char *obj)
{
cout << "fun3捕获到一个异常,交由上层处理" << endl;
throw; //向上抛 自身不对异常做处理
}
catch(...) //多级catch 类似于switch语句中的case逐级匹配数据 如果都没有匹配到,就用三个...
{
cout << "捕获其他异常" << endl;
}
cout << "fun3函数调用结束" << endl;
}
int main()
{
try
{
fun3();
}
catch(const char* obj)
{
cout << "main函数捕获到一个异常:" << obj << endl; //子函数向上抛 就抛在这 对应相应的异常处理
}
catch(...)
{
cout << "main 函数捕获其他异常" << endl;
}
return 0;
}
对异常捕获的几点说明:
(1)将可能抛出异常的程序段放在try{}块中
(2)如果在保护段执行期间没有引起异常,那么跟在try{}块后的catch()子句就不执行。直接转到最后一个catch子句后边的语句继续执行程序。
(3)如果匹配的处理未找到,则自动运行函数terminate,其缺省功能是调用abort终止程序。
(4)对于处理不了的异常,可以在catch的最后一个分支,使用throw语法,向上抛。
(5)异常是跨函数的。
三:异常标准库
#include <iostream>
#include <stdexcept>
using namespace std;
class Student
{
private:
int id;
public:
Student(int i):id(i)
{
if(i < 0)
{
throw out_of_range("id不能小于0"); //异常名称一定要写 out_of_range();
}
//id = i;
}
};
int main()
{
try
{
Student s(-10);
}
catch(exception &obj) //标准库exception
{
printf("捕获到一个异常:%s\n",obj.what()); //基类exception提供一个虚函数what(),用来返回错误信息
}
catch(...)
{
cout << "捕获其他异常" << endl;
}
return 0;
}
四:栈解旋
//栈解旋:异常抛出后,从进入try{}起,到异常被抛之前,这期间在栈上构造的所有对象,都会被自动析构。
#include <iostream>
using namespace std;
/*class Test
{
public:
Test()
{
cout << "Test构造函数" << endl;
}
~Test()
{
cout << "Test析构函数" << endl;
}
};*/
//int Div(int x, int y) throw(int , char , char* ); //可以抛出int,char char*类型 若抛出float则在try{}模块检测不到
//int Div(int x, int y) throw(); //不会抛出异常
int Div(int x, int y) //可以抛出任意类型的异常
{
if(y == 0)
{
throw "被除数不能为0";
}
return x/y;
}
int main()
{
int x,y;
cin >> x >> y;
try
{
//Test t;
cout << Div(x,y) << endl; //若检测到异常 后边的程序不会执行
cout << "12345" << endl;
}
catch(const char* &obj)
{
cout << "捕获到异常" << endl;
cout << obj << endl;
}
catch(...)
{
cout << "捕获其他异常" << endl;
}
return 0;
}
五:异常的生命周期
#include <iostream>
using namespace std;
class Test
{
public:
Test()
{
cout << "Test构造函数" << endl;
}
Test(const Test &obj)
{
cout << "Test拷贝构造函数" << endl;
}
void show()
{
cout << "异常错误" << endl;
}
~Test()
{
cout << "Test析构函数" << endl;
}
};
int Div(int x, int y) //可以抛出任何异常
{
if(y == 0)
{
throw Test(); //对应主函数的对象 注意:抛出异常后以下程序都不会执行
//throw new Test(); //对应主函数的指针 抛出指针异常
}
return x/y;
}
int main()
{
int a,b;
cin >> a >> b;
try
{
cout << Div(a,b) << endl;
}
/*catch(Test t) //结果调用两次构造和析构
{
t.show();
}*/
catch(Test &t) //同上都可以使用 但这个更好 结果调用一次构造和析构
{
t.show();
}
catch(Test *t)
{
t->show();
delete t;
}
catch(...)
{
cout << "捕获其他异常" << endl;
}
return 0;
}