C++异常处理
当异常发生的时候,会提出一个转移控制权的方式通常是通过以下三个关键字来实现的:
- throw 当问题出现的时候,抛出一个异常
- catch 在想要处理异常的地方使用catch来捕获异常
- try try块中的代码将要标识被激活的特定异常,通常后面跟着很多catch
通常来讲,try中的代码是可能出现异常的代码,可以称之为保护代码,try之后的catch用于捕获异常
例子如下:(相当于一个switch,try产生一个异常,根据不同的情况会被不同的catch捕获)
try
{
//可能出现异常的代码
}
catch(异常名称 e1)
{
//处理块
}
catch(异常名称 e2)
{
//处理块
}
...
catch(异常名称 en)
{
//处理块
}
可以使用 throw 语句在代码块中的任何地方抛出异常。throw 语句的操作数可以是任意的表达式,表达式的结果的类型决定了抛出的异常的类型。
例如:
int div(int a, int b)
{
if( b == 0 )
{
throw "b==0";
}
return (a/b);
}
注意,当我们使用throw的时候,throw后面可以跟任意类型的数据类型,catch到的是数据类型
例子:
#include <iostream>
using namespace std;
double division(int a, int b)
{
if (b == 0)
{
//throw "Division by zero condition!"; //类型是char *
//throw (float)1.2; //原来的类型是double,使用强制转换之后能够成为我们想要的类型,要不然会跳过我们定义的float
//throw (unsigned)1; //原来是int类型
throw '1'; //如果没有对应的catch的话,就相当于除以0操作,直接导致程序崩溃
//当有数字的时候,我们可以使用强制转换类型来达到我们想要的类型,进而进行catch
}
return (a / b);
}
int main()
{
int x = 50;
int y = 0;
double z = 0;
try {
z = division(x, y);
cout << z << endl;
}
catch (char* msg) {
cerr << msg << endl;
}
catch (int a) {
cerr << a << " int"<< endl;
}
catch (unsigned k) {
cerr << k << " intzz" << endl;
}
catch (float n)
{
cerr << n << " float" << endl;
}
catch (double m)
{
cerr << m <<" double"<< endl;
}
return 0;
}
也可以实现自己定义异常类型
例子
#include <iostream>
#include <exception>
using namespace std;
class MyException : public exception
{
public:
const char * what() const throw () //这个throw表示异常规范说明what()是变量类型,调用之后返回自己定义的错误信息
{
return "C++ Exception";
}
};
int main()
{
try
{
MyException m;
throw m;
}
catch (MyException& e)
{
std::cout << "MyException caught" << std::endl;
std::cout << e.what() << std::endl;
}
catch (std::exception& e)
{
//其他的错误
}
}
异常规范说明:
异常规格说明的目的是为了让函数使用者知道该函数可能抛出的异常有哪些。
可以在函数的声明中列出这个函数可能抛掷的所有异常类型。
例如:
void fun() throw(A,B,C,D);
2、若无异常接口声明,则此函数可以抛掷任何类型的异常。
3、不抛掷任何类型异常的函数声明如下:
void fun() throw();
例子:
#include <iostream>
#include <exception>
using namespace std;
class MyException
{
public:
MyException(const char *message)
: message_(message) //初始化
{
cout << "MyException ..." << endl;
}
MyException(const MyException &other) : message_(other.message_)
{
cout << "Copy MyException ..." << endl;
}
virtual ~MyException()
{
cout << "~MyException ..." << endl;
}
const char *what() const
{
return message_.c_str();
}
private:
string message_;
};
class MyExceptionD : public MyException
{
public:
MyExceptionD(const char *message)
: MyException(message)
{
cout << "MyExceptionD ..." << endl;
}
MyExceptionD(const MyExceptionD &other)
: MyException(other)
{
cout << "Copy MyExceptionD ..." << endl;
}
~MyExceptionD()
{
cout << "~MyExceptionD ..." << endl;
}
};
void fun(int n) throw (int, MyException, MyExceptionD)
{
if (n == 1)
{
throw 1;
}
else if (n == 2)
{
throw MyException("test Exception");
}
else if (n == 3)
{
throw MyExceptionD("test ExceptionD");
}
}
void fun2() throw()
{
}
int main(void)
{
try
{
fun(2);
}
catch (int n)
{
cout << "catch int ..." << endl;
cout << "n=" << n << endl;
}
catch (MyExceptionD &e)
{
cout << "catch MyExceptionD ..." << endl;
cout << e.what() << endl;
}
catch (MyException &e)
{
cout << "catch MyException ..." << endl;
cout << e.what() << endl;
}
return 0;
}
有关声明的异常处理的使用
#include <iostream>
#include <string>
using namespace std;
class MyException
{
public:
MyException(const char *message)
: message_(message)
{
cout << "MyException ..." << endl;
}
MyException(const MyException &other) : message_(other.message_)
{
cout << "Copy MyException ..." << endl;
}
virtual ~MyException()
{
cout << "~MyException ..." << endl;
}
const char *what() const
{
return message_.c_str();
}
private:
string message_;
};
class MyExceptionD : public MyException
{
public:
MyExceptionD(const char *message)
: MyException(message)
{
cout << "MyExceptionD ..." << endl;
}
MyExceptionD(const MyExceptionD &other)
: MyException(other)
{
cout << "Copy MyExceptionD ..." << endl;
}
~MyExceptionD()
{
cout << "~MyExceptionD ..." << endl;
}
};
int main(void)
{
try
{
MyExceptionD e("test exception");
throw e;
}
catch (MyExceptionD &e)
{
cout << "catch MyExceptionD ..." << endl;
cout << e.what() << endl; //重新定义的函数
}
catch (MyException &e)
{
cout << "catch MyException ..." << endl;
cout << e.what() << endl;
}
return 0;
}
其中核心还是根据生命的不同类型来进行不同的catch