C++异常
1、异常的抛出以及捕获
try
{
throw 异常值;
}
catch(异常类型1 异常值1)
{
处理异常的代码1;
}
catch(异常类型2 异常值2)
{
处理异常的代码2;
}
catch(...)//任何异常都捕获
{
处理异常的代码3;
}
int main()
{
try{
// throw 0; //int
// throw 'a'; //char
throw "hello";//const char *
}
catch(int e){
cout<<"接收到异常e="<<e<<endl;
}
catch(char e){
cout<<"接收到异常e="<<e<<endl;
}
catch(...){
cout<<"接受到其他类型的异常"<<endl;
}
return 0;
}
2、栈解旋
异常被抛出后,从进入try块起,到异常被抛掷前,这期间在栈上构造的所有对
象,都会被自动析构。析构的顺序与构造的顺序相反,这一过程称为栈的解旋.
class Data{
public:
int a;
public:
Data(){}
Data(int a){
this->a=a;
}
~Data(){
cout<<"析构函数"<<this->a<<endl;
}
};
int main()
{
try{
Data ob1(1);
Data ob2(2);
Data ob3(3);
throw 0; //int
// throw 'a'; //char
// throw "hello";//const char *
}
catch(int e){
cout<<"接收到异常e="<<e<<endl;
}
catch(char e){
cout<<"接收到异常e="<<e<<endl;
}
catch(...){
cout<<"接受到其他类型的异常"<<endl;
}
return 0;
}
析构函数3
析构函数2
析构函数1
接收到异常e=0
3、异常的接口声明
异常的接口声明:描述的是 可以抛出哪些类型的异常
//不能抛出 任何异常
void fun03() throw()//没有声明抛出异常的类型
{
throw 1;//抛出 不能捕获
}
void fun02() throw(int,char)//只能捕获int和char类型的异常
{
//throw 1;//抛出 可以捕获int
//throw 'a';//抛出可以捕获char
throw "hello";//抛出 不能捕获
}
int main()
{
try{
fun03();
}
catch(int e){
cout<<"接收到异常e="<<e<<endl;
}
catch(char e){
cout<<"接收到异常e="<<e<<endl;
}
return 0;
}
4、异常变量的生命周期
1、以普通对象接异常值
class MyException{
public:
MyException(){
cout<<"构造函数"<<endl;
}
MyException(const MyException &e){
cout<<"拷贝构造发生"<<endl;
}
~MyException(){
cout<<"析构函数"<<endl;
}
};
int main()
{
try{
throw MyException();//无参构造
}
catch(MyException e ){//普通对象接收异常,拷贝构造发生
cout<<"接收到异常"<<endl;
}
return 0;
}
构造函数
拷贝构造发生
接收到异常
析构函数
析构函数
2、以对象指针接异常值
class MyException{
public:
MyException(){
cout<<"构造函数"<<endl;
}
MyException(const MyException &e){
cout<<"拷贝构造发生"<<endl;
}
~MyException(){
cout<<"析构函数"<<endl;
}
};
int main()
{
try{
throw new MyException;//指针对象
}
catch(MyException *e ){//
cout<<"接收到异常"<<endl;
delete e;
}
return 0;
}
构造函数
接收到异常
析构函数
3、对象引用接异常值(推荐)
class MyException{
public:
MyException(){
cout<<"构造函数"<<endl;
}
MyException(const MyException &e){
cout<<"拷贝构造发生"<<endl;
}
~MyException(){
cout<<"析构函数"<<endl;
}
};
int main()
{
try{
throw MyException();
}
catch(MyException &e){
cout<<"接收到异常"<<endl;
}
return 0;
}
构造函数
接收到异常
析构函数
5、异常的多态
//异常基类
class BaseException{
public:
virtual void printError(){}
};
class NullPointException :public BaseException{
public:
virtual void printError(){//重写printError
cout<<"空指针异常"<<endl;
}
};
int main()
{
try{
throw NullPointException();
}
catch(BaseException &e){//父类异常
e.printError();
}
return 0;
}
6、c++标准异常
int main()
{
try{
throw out_of_range("哈哈,我越界了");
}
catch(exception &e){
cout<< e.what()<<endl;//通过what函数打印异常信息
}
return 0;
}
7、编写自己的异常
编写字节的异常:基于标准异常
自己的异常 一定要从exception上继承
class MyException:public exception{
private:
string msg;
public:
MyException(){}
MyException(string msg){
this->msg=msg;
}
virtual const char * what()const throw()//const throw()防止父类在子类前抛出标准异常
{
cout<<this->msg<<endl;
}
};
int main()
{
try{
throw MyException("自定义异常");
}
catch(exception &e){
cout<< e.what()<<endl;
}
return 0;
}