异常处理

throw:自己无法处理的异常抛出

try:把可能抛出异常的代码括起来

catch:处理异常

面向对象角度:处理完异常,程序可以继续执行,并使得所有的异常可以集中处理

异常的栈展开:即就是栈上的子函数有异常抛出时,先在子函数中找是否有相应的catch,如果没有,就逐层往下找,直到找到主函数也没有相应的catch话,那么异常将会被抛给系统,系统会调用terminate函数的abort函数,终止程序。如果找到catch就进行相应的处理。

try和catch是配对使用的,当try出现的时候,catch也应出现。

catch(argument ) — catch的参数是处理异常的类型

catch(…) ——表示可以处理所有类型,一般放在catch子句最后

catch子句从上往下逐句执行,执行有严格的顺序

如果try语句段中有三个语句,当第二个语句抛出异常之后,就会有相应的catch来执行它,捕获异常之后,编译器就会忽略try之后未被执行的语句,而从最后一个catch之后开始执行。

int fun(int);
void main()
{
    try
    {
        cout << "4 != " << fun(4) << endl;
        cout << "-2 != " << fun(-2) << endl;
        //由于上一条语句抛出异常,该语句未被执行,只要找到一个匹配的异常类型,后面的异常处理都将被忽略
        cout << "-3 != " << fun(-3) << endl;
    }
    catch (int n)
    {
        cout << "n=" << n << "不能计算n!" << endl;
    }
    cout << "程序执行结束";
}
int fun(int n)
{
    if (n <= 0)
        throw n;
    int s = 1;
    for (int i = 1; i <= n; i++)
    {
        s*=i;
    }
    return s;
}

这里写图片描述
什么情况下抛出何种异常呢?

Int func( ) throw() //表示该函数不能抛出异常
{
}
Int func( ) //什么都不写,表示该函数可抛出任意类型异常
{
}
Int func( ) throw(int) //表示该函数可抛出整型类型异常
{
}

当抛出一个异常的对象的时候,全局异常存储区域拷贝构造给全局的异常对象(编译器)
在建立起catch的形参之后,就析构之前拷贝构造给全局对象的对象。

template<typename T>
class CExcep
{
public:
    CExcep(string info, T data) 
    {
        _info=info;
        _data=data;

    }
    virtual void show()const
    {
        cout << "info:" << _info << " data:" << _data << endl;
    }
    protected:
    string _info;
    T _data;
};

template<typename T>
class CFullExcep : public CExcep<T>
{
public:
    CFullExcep(string info, T data) :CExcep<T>(info, data)
    {
        cout << this << endl;
        cout << "CFullExcep()" << endl;
    }
    CFullExcep(const CFullExcep<T> &src) :_info(src._info), _data(src._data)
    {
        cout << &src << "->" << this << endl;
        cout << "CFullExcep(const CFullExcep<T>&)" << endl;
    }
    ~CFullExcep()
    {
        cout << this << endl;
        cout << "~CFullExcep()" << endl;
    }
    void show()const
    {
        cout << "CFullExcep<T>::show" << endl;
        CExcep<T>::show();
    }
};

template<typename T>
class CArray
{
public:
    CArray(int size) :msize(size <= 0 ? 5 : size), mcur(0)
    {
        cout << this << endl;
        //throw "";
        cout << "CArray()" << endl;
        mpArr = new T[msize];
    }
    ~CArray()
    {
        cout << this << endl;
        cout << "~CArray()" << endl;
        delete[]mpArr;
        mpArr = NULL;
    }

    void push_back(const T &val)    //异常规范
    {
        if (mcur >= msize)
        {
            //throw "array is full!";
            // 全局的异常存储区域  ->   全局的异常对象  
        //throw CFullExcep<T>("array is full!", val);  
            /*CFullExcep<T> tmp("array is full!", val);
            throw tmp;*/
            CFullExcep<T> tmp("array is full!", val);
            CExcep<T> *ptr = &tmp;
            throw *ptr;
        }

        mpArr[mcur++] = val;
    }
private:
    T *mpArr;
    int mcur;
    int msize;
};
int main()
{
    CArray<int> array(2);
    int arr[10];

    for (int i = 0; i < 10; ++i)
    {
        arr[i] = rand() % 100 + 1;
    }

    try
    {
        for (int i = 0; i < 10; ++i)
        {
            array.push_back(arr[i]);
        }
    }
    catch (const char *errstr)
    {
        cerr << errstr << endl;
    }
    catch (const CFullExcep<int> &err)
    {
        err.show();
    }
    catch (const CExcep<int> &err)
    {
        err.show();
    }

    return 0;
}

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值