C++学习笔记13--异常处理

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++学习笔记13--异常处理相关的知识,希望对你有一定的参考价值。

异常处理

    什么是异常:不常发生但无法避免。

      返回错误码

      设置errno全局变量

      抛出异常

    捕获异常:

      用Try{}把可能发生异常的代码包起来紧跟其后用若干个(至少一个)catch(类型 e){}来捕获指定类型的异常并处理,处理后程序从最后一个catch块后继续运行。

      抛出异常:throw 数据;

    被Throw拋出的异常数据不受作用范围的限制,直到被捕获被处理为止,因此在捕获时可以通过引用来访问异常数据。即使已经被处理的异常数据,也可以用一个不带数据的throw重新抛出。

    如果抛出的异常没有被捕获处理,系统会调用terminate()函数终止程序。set_terminate(fun)可以指定在terminate时自动调用func函数。

    异常传递机制:从throw开始离开正常执行流程,在本函数内找有没有包含它的try{}块,如果有依次查找它的catch块直到第一个类型匹配的为止进入这个catch块执行处理,之后从最后一个catch块之后继续执行;如果没有包含它的try{}块或者没有类型匹配的catch块,异常数据继续传递到上层函数(调用它的那个函数)中重复这个过程,如果直到Main函数还没有处理,就会传递给内核,系统就会调用terminate终止程序

    多个catch块如果同时有父类类型和子类类型,应该把子类类型放在前面,如果有一个是catch(...),它必须放在最后。

#include<iostream>
using namespace std;
#include<string>

void f1()
{
    try{
        cout<<"1--int\n2--double\n0--return\n";
        int n;
        cin>>n;
        if(n==1) throw 1;
        if(n==2) throw 2.2;
        if(n==0) return;
        throw string("error");
    }
    catch(long e){cout<<"long "<<e<<endl;}
    catch(double e){cout<<"double "<<e<<endl;}
    cout<<"----endl of f1----"<<endl;
}
void f2()
{
try{
        f1();
        cout<<"----in f2----"<<endl;
    }
    catch(int e){cout<<"int "<<e<<endl;}
    cout<<"----end of f2----"<<endl;
}

int main()
{
    try{
        f2();
    }
    catch(...) {cout<<"发生异常"<<endl;}
    cout<<"我还会回来的"<<endl;
    system("pause");
}

 

    异常申明:一个函数可以声明自己可能抛出哪些类型的异常,格式为

      返回类型 函数名(参数表) throw(异常类型列表);

      int func(int a[],int idx) throw(double,int,string);

    如果在函数内部抛出了不在列表中的异常,则会引发意外。unexpected 可以通过set_unexpected(func)来设置遇到意外的情况时调用func来设置遇到意外情况时调用func.没有异常声明表示可能抛出任何类型的异常,空异常列表表示不会抛出异常

#include<iostream>
using namespace std;
#include<exception>

void f1(int n)throw(int,double)
{
    try{
    if(n==1) throw 123;
    if(n==2) throw 4.5;
    throw "out of range";
    }
    catch(int e){
     cout<<"catch "<<e<<" in f1"<<endl;
     if(e>100) throw;//重新抛出当前异常数据
    }
}
void func(){cout<<"异常类型不在列表中"<<endl;}

int main(int argc,char* argv[])
{//argument参数,cont数量,vector不定长数组
    set_unexpected(func);
    try{
        cout<<"argc="<<argc<<endl;
        f1(argc);
    }
    catch(int e){cout<<"int "<<e<<endl;}
    catch(double e){cout<<"double "<<e<<endl;}
    //catch(...){cout<<"exception"<<endl;}
    system("pause");
}

    标准异常:exception类,#include<exception>

    定义子类覆盖父类的虚函数时,异常声明的内容不能超出父类中异常声明的内容

    标准库中抛出的异常类型都是exception的子类

    自己定义异常类型一般继承exception类,覆盖const char* what() const throw()函数,返回一个字符串,描述发生了什么异常

    

#include<iostream>
using namespace std;
#include<exception>
#include<new>
#include<cstdio>

class A{//数组类
    int *p;
    int len;
public:
    explicit A(int n) throw(){
    p = new (nothrow) int[n];
    len = n;
    }
    int& operator[](int index){
        if(index<0) throw NegIndex(index);
        if(index>=len) throw OutofRange(index);
        if(p==NULL) throw MemoryException();
        return p[index];
    }
    class NegIndex : public exception{
        int i;
    public:
        NegIndex(int index)throw():i(index){};
        const char* what()const throw(){
            static char buf[100];
            sprintf(buf,"负下标异常%d",i);
            return buf;
        }
    };

    class OutofRange : public exception{
        int i;
    public:
        OutofRange(int index)throw():i(index){};
        const char* what()const throw(){
            static char buf[100];
            sprintf(buf,"越界%d",i);
            return buf;
        }
    };

    class MemoryException : public exception{
    public:
        const char* what()const throw(){
            return "内存不足";
        }
    };
};

int main()
{
    A x(10);
    x[0]  =5,x[3]=10,x[8]=20;
    cout<<x[3]*x[0]*x[8]<<endl;
    cout<<x[-5]<<endl;
    cout<<x[20]<<endl;
    system("pause");
}

  

以上是关于C++学习笔记13--异常处理的主要内容,如果未能解决你的问题,请参考以下文章

C++学习笔记:高级编程:文件和流,异常处理,动态内存,命名空间

Python学习笔记13(异常处理)

c++复习笔记——异常处理机制

PCL异常处理:pcl 1.8.13rdpartyoostincludeoost-1_64oost ypeofmsvc ypeof_impl.hpp(125): error(代码片段

Python 2.7 学习笔记 异常处理

Java异常处理_学习笔记