C++异常

异常是指存在于运行时的反常行为,这些行为超出了函数正常功能的范围。
所以在程序的某部分检测到一个它无法处理的问题时,需要用到异常处理。
首先我们先贴代码

#include "stdafx.h"
#include <iostream>
using namespace std;

template <class T>
class Vector {
public:
    Vector(int);
    ~Vector();
    Vector(const Vector&);
    Vector& operator=(const Vector& rhs);
    T& operator[](int);
private:
    T* m_elements;
    int m_size;
};

template <class T>
Vector<T>::Vector(int size) :m_size(size) {
    cout << "this is constructor" << endl;
    m_elements = new T[m_size];
}

template <class T>
Vector<T>::~Vector() {
    cout << "this is Destrucor" << endl;
    delete[] m_elements;
    m_elements = NULL;
}

template<class T>
Vector<T>::Vector(const Vector &)
{
    cout << "this is copy construcor" << endl;
}


template <class T>
Vector<T>& Vector<T>::operator=(const Vector& rhs) {
    cout << "this is = " << endl;

}

template <class T>
T& Vector<T>::operator[](int index) {
    if (index>0 && index<m_size) {
        return m_elements[index];
    }
    else {
        cout << "index is invalid" << endl;
    }
}//这样处理会发生异常,没有返回值

int main()
{
    Vector<int> v1(6);
    cout << "hello" << endl;
    int i = 1;
    for (; i < 6; i++) {
        v1[i] = i;
    }
    cout << i << endl;
    return 0;
}

异常时不良的处理有:

  • 1 返回值是不缺的内存的值
    return m_elements[index];
  • 2 错误时,返回一个错误值
T& Vector<T>::operator[](int index) {
    if (index<0 || index>=m_size) {
        T* error_marker = new T("something magic value");
        return *error_marker;
    }
    return m_elements[index];
}

x = v1[2] + v1[4]; //一旦v1[4]越界,则x无法计算
  • 3 退出处理
    if(index<0||index>=m_size){
         exit(666);
    }
    return m_elements[index];
  • 4 自动判断
assert(index>= 0&& intdex <m_size);
return m_elements[index];

所以这时候,我们可以用关键字 throw 抛出一个异常。

template <class T>
T& Vector<T>::operator[](int index) {
    if (index<0 || index>=m_size) {
        //throw is a keyword
        //exception is raised at this point
        throw <<something>>;
    }
    return m_elements[index];
}

可以通过原始类型或者一个类去表达这个error

class VectorIndexError{
public:
    VectorIndexError(int v):m_badValue(v){ }
    ~VectorIndexError(){ }
    void diagnostic(){
        cerr <<"index "<< m_badValue<<"out of range!";}
private:
    int m_badValue;
};

template <class T>
T& Vector<T>::operator[](int index) {
    if (index<0 || index>=m_size) {
        //throw is a keyword
        //exception is raised at this point
        throw VectorIndexError(index);
    }
    return m_elements[index];
}

#include "stdafx.h"

#include <iostream>
using namespace std;

template <class T>
class Vector {
public:
    Vector(int);
    ~Vector();
    Vector(const Vector&);
    Vector& operator=(const Vector& rhs);
    T& operator[](int);
private:
    T* m_elements;
    int m_size;
};

template <class T>
Vector<T>::Vector(int size) :m_size(size) {
    cout << "this is constructor" << endl;
    m_elements = new T[m_size];
}

template <class T>
Vector<T>::~Vector() {
    cout << "this is Destrucor" << endl;
    delete[] m_elements;
    m_elements = NULL;
}

template<class T>
Vector<T>::Vector(const Vector &)
{
    cout << "this is copy construcor" << endl;
}


template <class T>
Vector<T>& Vector<T>::operator=(const Vector& rhs) {
    cout << "this is = " << endl;

}

class VectorIndexError {
public:
    VectorIndexError(int v) :m_badValue(v) { }
    ~VectorIndexError() { }
    void diagnostic() {
        cerr << "index " << m_badValue << " out of range!" << endl;
    }
private:
    int m_badValue;
};

template <class T>
T& Vector<T>::operator[](int index) {
    if (index<0 || index >= m_size) {
        //throw is a keyword
        //exception is raised at this point
        throw VectorIndexError(index);
    }
    return m_elements[index];
}



int func() {
    Vector<int> v(12);
    v[3] = 5;
    int i = v[20];  //out of range!
                    //control never get here
    return 5 * i;
}

void outer() {
    try {
        func();
        //func2();
    }
    catch (VectorIndexError& o) {
        o.diagnostic();
        //This exception does not propagate
    }
    cout << "Control is here after exception";
}

int main()
{
    Vector<int> v1(6);
    cout << "hello" << endl;
    int i = 1;
    for (; i < 6; i++) {
        v1[i] = i;
    }
    cout << i << endl;
    cout << "do exception test" << endl;
    outer();
    cout << endl;
    return 0;
}

所以异常处理包括:

  • throw 表达式,异常检测部分使用 throw 表达式来表示遇到了无法处理的异常问题,即 throw 引发了异常。
  • try 语句块,异常处理部分使用 try 语句块处理异常。try 语句块以关键字 try 开始,并以一个或多个 catch 子句解释。

下面给出一个

#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;

template <class T>
class Vector {
public:
    Vector(int);
    ~Vector();
    Vector(const Vector&);
    Vector& operator=(const Vector& rhs);
    T& operator[](int);
private:
    T* m_elements;
    int m_size;
};

template <class T>
Vector<T>::Vector(int size) :m_size(size) {
    cout << "this is constructor" << endl;
    m_elements = new T[m_size];
}

template <class T>
Vector<T>::~Vector() {
    cout << "this is Destrucor" << endl;
    delete[] m_elements;
    m_elements = NULL;
}

template<class T>
Vector<T>::Vector(const Vector &)
{
    cout << "this is copy construcor" << endl;
}


template <class T>
Vector<T>& Vector<T>::operator=(const Vector& rhs) {
    cout << "this is = " << endl;

}

template <class T>
T& Vector<T>::operator[](int index) {
    if (index<0 || index >= m_size) {
        //throw is a keyword
        //exception is raised at this point
        throw VectorIndexError(index);
    }
    return m_elements[index];
}

class VectorIndexError {
public:
    VectorIndexError(int v) :m_badValue(v) { }
    ~VectorIndexError() { }
    void diagnostic() {
        cerr << "index " << m_badValue << " out of range!" << endl;
    }
private:
    int m_badValue;
};

int func() {
    Vector<int> v(12);
    v[3] = 5;
    int i = v[20];  //out of range!
                    //control never get here
    return 5 * i;
}

void outer() {
    try {
        func();
        //func2();
    }
    catch (VectorIndexError& o) {
        o.diagnostic();
        //This exception does not propagate
    }
    cout << "Control is here after exception";
}

void outer2() {
    string err("exception caught");
    try {
        func();
        //func2();
    }
    catch (VectorIndexError) {
        cout << err << endl;
        throw;  //propagate the exception
    }
}

void outer3() {
    try {
        outer2();
    }
    catch(...){
        //... means catchs ALL exception no matter what types(int ,double class exception types)
        cout << "The exception stops here!" << endl;
    }
}

int main()
{
    Vector<int> v1(6);
    cout << "hello" << endl;
    int i = 1;
    for (; i < 6; i++) {
        v1[i] = i;
    }
    cout << i << endl;
    cout << "do exception test" << endl;
    outer();
    cout << endl;
    cout << "do exception test2" << endl;
    //outer2();
    //cout << endl;
    outer3();
    return 0;
}

机制如下图所示:
这里写图片描述

异常处理的步骤是:
先顺序执行 throw 表达式,在每一个 throw 表达式里面按顺序执行:

  • 1 Check for exact match
  • 2.Apply base class conversions
    –Reference and pointer types only

  • 3.Ellipses(…)match all

其中, throw 表达式可以理解成函数调用,表达式类型就是异常抛出的类型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值