一、c++ 异常处理是通过try catch语句来执行的
try
{
//语句体
//如果语句体没有正常执行则抛出异常,
throw error //抛出异常
}
catch(DataType& e) //捕获抛出的异常,按error的数据类型捕获
{
//语句体,一般包括以下:
cerr << "输出异常信息" << endl;
exit(1); //非正常退出程序,要包含头文件<unistd.h>和<cstdlib>
}
catch()
{}
...
二、try{语句体}:
语句体中的throw error可以直接在try中抛出,也可以通过try中的函数抛出
例:直接在try中抛出
try
{
int a = 8;
int b = 0;
if(b==0)
throw 0;
double c = a/(double)b;
}
也可以在try调用的函数中抛出
double func1(int x, int y)
{
if(y==0)
throw y;
double c = x/y;
return c;
}
try
{
int a = 8;
int b = 0;
double c = func1(a,b); //在func1中抛出异常,throw的异常可以从所在的函数中按函数被调用的顺序一直向上传递,即也可以在func1中调用的函数里throw
}
三、catch 语句
catch(int& i) //捕获在try中throw的数据为int类型
{
cerr << "throw a int error" << endl; //也可以cout更具实际意义的信息
exit(1); //非正常退出程序
}
catch(Mytype& d) // 也可以是自定义的类型
{
cout << "throw a Mytype error" << endl;
exit(1);
}
catch(exception& e) // exception标准错误类型,包含头文件<exception>
{
cerr << "throw a 标准错误类" << endl;
exit(1);
}
catch(...) //任意类型
{
cerr << "throw a ..." << endl;
exit(1);
}
四、
例1:简单例子
#include <unistd.h>
#include <cstdlib>
#include <iostream>
using namespace std;
double func1(int x, int y)
{
if(y==0)
throw y;
double c = x/y;
return c;
}
int main()
{
try
{
int a = 8;
int b = 0;
double c = func1(a,b);
}
catch(int& i) //throw的y是int,所以被参数int类型的catch捕获
{
cerr << "y值错误,可能除0,y=" << i << endl;
exit(1); //非正常退出程序
}
catch(double& d)
{
cout << "throw a double error" << endl;
exit(1);
}
catch(...) //任意类型
{
cerr << "throw a ..." << endl;
exit(1);
}
return 0;
}
程序运行结果
例2:任意类型错误
#include <unistd.h>
#include <cstdlib>
#include <iostream>
#include <exception>
#include <string>
using namespace std;
int main()
{
try
{
int a = 8;
int b = 0;
if(b==0)
throw "error";
}
catch(int& i) //捕获在try中throw的数据为int类型
{
cerr << "y值错误,可能除0,y=" << i << endl; //也可以cout更具实际意义的信息
exit(1); //非正常退出程序
}
catch(...) //任意类型,捕获不在以上catch中定义的throw类型,“error”不属于以上catch中的类型
{
cerr << "throw a ..." << endl;
exit(1);
}
return 0;
}
运行结果:
例3:自定义类型错误
#include <unistd.h>
#include <cstdlib>
#include <iostream>
#include <string>
class Mytype
{
public:
Mytype(string str) : error(str){}
void PrintError()
{
cout << error << endl;
}
private:
string error;
};
int main()
{
try
{
int a = 8;
int b = 0;
if(b==0)
throw Mytype("this is Mytype error");
}
catch(int& i) //捕获在try中throw的数据为int类型
{
cerr << "y值错误,可能除0,y=" << i << endl; //也可以cout更具实际意义的信息
exit(1); //非正常退出程序
}
catch(Mytype& d) // 捕获自定义的类型Mytype类的错误
{
d.PrintError();
exit(1);
}
catch(...) //任意类型
{
cerr << "throw a ..." << endl;
exit(1);
}
return 0;
}
运行结果:
例4:标准类型错误
需要包含头文件<exception>
#include <unistd.h>
#include <cstdlib>
#include <iostream>
#include <exception>
#include <string>
using namespace std;
//定义继承自exception类的子类DivException
class DivException:public exception
{
private:
const char* ptr;
public:
DivException(const char * ptr1) : ptr(ptr1){}
//重写虚函数what()
virtual char const* what() const throw() // 函数名后面的const表示what是常成员函数,它只能对类成员变量读,不能写(即不能改变成员变量的值),否则报错
{
return ptr;
}
};
int main()
{
try
{
int a = 8;
int b = 0;
if(b==0)
throw DivException("标准错误类");
}
catch(int& i) //捕获在try中throw的数据为int类型
{
cerr << "y值错误,可能除0,y=" << i << endl; //也可以cout更具实际意义的信息
exit(1); //非正常退出程序
}
catch(Mytype& d) // 也可以是自定义的类型
{
d.PrintError();
exit(1);
}
catch(exception& e) // exception标准错误类型,包含头文件<exception>
{
cerr << e.what() << endl;
exit(1);
}
catch(...) //任意类型
{
cerr << "throw a ..." << endl;
exit(1);
}
return 0;
}
运行结果:
注意重写what()函数:
virtual char const* what() const throw()
函数名后的throw():
void func() throw() //表示func()不允许抛出任何异常,即func()是异常安全的
void func() throw(type) //表示func()只允许抛出type 类型的异常
void func() throw(...) //表示func()允许抛出任何异常
func()后不加throw也表示可以抛出任何异常