一.异常
1.异常的抛出和捕获
使用throw抛出异常,并需要使用catch进行捕获,若没有捕获程序将结束
try{
throw 异常值;
}
catch(异常类型1 异常值1){
处理异常的代码1;
}
catch(异常类型2 异常值2){
处理异常的代码2;
}
...
2.栈解旋
try代码块范围里,在异常抛出之前,申请在栈中的所有对象都会被自动析构,这一个过程就是栈的解旋,其析构的顺序于构造的顺序相反
3.异常的接口声明
其是描述该函数能抛出什么类型的异常
3.1 函数默认抛出所有的异常(推荐)
void func1(){
//throw 1;
//throw '1';
throw "hello"';
}
3.2 只能抛出特定类型异常
void func1() throw(int,char)
{
throw 1;
throw '1';
//throw "hello"';//抛出但捕获不了
}
3.3 不能抛出任何异常
void fun3() throw()
{
//throw 1;
//throw '1';
throw "hello"';//抛出但捕获不了
}
4.异常的接取
异常类
class MyException
{
public:
MyException(){
cout<<"异常变量构造"<<endl;
}
MyException(const MyException &e){
cout<<"拷贝构造"<<endl;
}
~MyException(){
cout<<"异常变量析构"<<endl;
}
};
4.1 用普通对象接异常值
try
{
throw MyException();
}
catch(MyException e){//普通对象接异常会调用拷贝构造函数
cout<<"普通对象接异常"<<endl;
}//会调用两次析构函数
4.2 用对象指针接异常
try
{
throw new MyException;
}
catch(MyException *e){
cout<<"普通对象接异常"<<endl;
delete e;
}//需要手动释放动态空间
4.3 用对象引用接异常(推荐)
try
{
throw MyException();
}
catch(MyException &e){
cout<<"普通对象接异常"<<endl;
}//会自动释放对象
5.异常的多态
使用虚函数来让子类重写,让父类来指向子类
class BaseException{
public:
virtual void printError(){};
};
class NullPointerException : public BaseException{
public:
virtual void printError(){
cout<<"空指针异常"<<endl;
}
}
6.自定义异常
- 需要公共继承exception
- 重写父类的what函数
#includ <exception>
class NewException:public exception{
private:
string msg;
public:
NewException(){}
NewException(string msg){
this->msg = msg;
}
//重写父类的what
virtual const char* what() const throw()//const throw()是为了防止父类在子类前抛出标准异常
{
//将string类转换成char*
return this->msg.c_str();
}
~NewException(){}
};
int main(){
try
{
throw NewException("自定义异常");
}
catch(exception &e){
cout<<e.what()<<endl;
}
}