一、整体代码
#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;
}
~MyException()
{
cout<<"~MyException"<<endl;
}
const char* what() const
{
return message_.c_str();
}
private:
string message_;
};
double Divide(double a, double b) throw (MyException)//只能抛出这一个异常
{
if (b == 0.0)
{
MyException e("division by zero");//调用构造函数
throw e;//调用拷贝构造函数,成为全局变量
//throw MyException("division by zero");//只调用构造函数
//throw 1.0;//抛出浮点数异常
}
else
return a / b;
}
class Obj
{
public:
Obj()
{
cout<<"Obj ..."<<endl;
}
Obj(const Obj& other)
{
cout<<"Copy Obj ..."<<endl;
}
~Obj()
{
cout<<"~Obj ..."<<endl;
}
};
class Test2
{
public:
Test2()
{
obj_ = new Obj;
cout<<"Test2 ..."<<endl;
//throw MyException("test exception2");//在对象还没有构造完成时,就抛出了异常
}
Test2(const Test2& other)
{
cout<<"Copy Test2 ..."<<endl;
}
~Test2()
{
delete obj_;
cout<<"~Test2 ..."<<endl;
}
private:
Obj* obj_;
};
int main(void)
{
try
{
Test2 t2;//局部变量,栈展开时候释放
cout<<Divide(5.0, 0.0)<<endl;
}
catch (MyException& e)
{
cout<<e.what()<<endl;
}
catch (int)
{
cout<<"int exception ..."<<endl;
}
catch (double)
{
cout<<"double exception ..."<<endl;
}
catch (...)//任何异常都能catch到
{
cout<<"catch a exception ..."<<endl;
}
}
二、结果
MyException e("division by zero");//调用构造函数
throw e;//调用拷贝构造函数,成为全局变量
//throw MyException("division by zero");//只调用构造函数
//throw 1.0;//抛出浮点数异常
throw异常前面的代码,如果有变量要进行释放。比如test2还有MyException
//MyException e("division by zero");//调用构造函数
//throw e;//调用拷贝构造函数,成为全局变量
throw MyException("division by zero");//只调用构造函数
//throw 1.0;//抛出浮点数异常
此时结果如下:
obj_ = new Obj;
cout<<"Test2 ..."<<endl;
throw MyException("test exception2");//在对象还没有构造完成时,就抛出了异常
如果Test2构造函数中,抛出异常,那么类此时还没有构造完成,此时不会调用析构函数
如果在栈控件分配了Obj,由于栈展开,即使类没有构造完成,也可以释放掉。
三、解释
throw() 说明不能抛出异常
throw(MyException) 只能抛出MyException
如果异常未被捕获会出现下面的效果:被系统捕获了