欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C++中的异常处理教程(下)

程序员文章站 2023-08-31 19:34:59
一、c++中的异常处理 catch语句块中可以抛出异常 catch中捕获的异常可以被重新解释后抛出 工程开发中使用这样的方式统一异常类型 实验:异常的重新解释 #include using...

一、c++中的异常处理

catch语句块中可以抛出异常

C++中的异常处理教程(下)

catch中捕获的异常可以被重新解释后抛出

工程开发中使用这样的方式统一异常类型

C++中的异常处理教程(下)

实验:异常的重新解释

#include
using namespace std;

void demo(){
    try{
        try{
            throw 'c';
        }
        catch(int i){
            cout <<"inner:catch(int i)" << endl;
            throw i;
        }
        catch(...){
            cout << "inner:catch(...)" << endl;
            throw;
        }
    }
    catch(...){
        cout << "outer:catch(...)" << endl;
    }
}

/*
    假设: 当前的函数式第三方库中的函数,因此,我们无法修改源代码

    函数名: void func(int i)
    抛出异常的类型: int
                        -1 ==> 参数异常
                        -2 ==> 运行异常
                        -3 ==> 超时异常
*/

void func(int i){
    if(i < 0){
        throw -1;
    }
    if(i > 100){
        throw -2;
    }
    if(i == 11){
        throw -3;
    }
    cout << "run func..." << endl;
}

void myfunc(int i){
    try{
        func(i);
    }
    catch(int i){
        switch(i){
            case -1:
                throw "invalid parameter";
                break;
            case -2:
                throw "runtime exception";
                break;
            case -3:
                throw "timeout exception";
                break;
        }
    }
}

int main(int argc,char *argv[]){
    try{
        myfunc(11);
    }
    catch(const char* cs){
        cout << "exception info:" << cs << endl;
    }
    return 0;
} 

打印结果:

exception info:timeout exception
异常的类型可以是自定义类类型 对于类类型异常的匹配依旧是自上而下严格匹配 赋值兼容性原则在异常匹配中依然适用 一般而言
匹配子类异常的catch放在上部 匹配父类异常的catch放在下部
在工程中会定义一系列的异常类 每个类代表工程中可能出现的一种异常类型 代码复用时可能需要重解释不同的异常类 在定义catch语句块时推荐使用引用作为参数

编程实验:类类型的异常

#include
#include
using namespace std;

class base{
};

class exception : public base{
    int m_id;
    string m_desc;
    public:
        exception(int id,string desc){
            m_id = id;
            m_desc = desc;
        }
        int id() const{
            return m_id;
        }
        string description() const{
            return m_desc;
        } 
};

/*
    假设: 当前的函数式第三方库中的函数,因此,我们无法修改源代码

    函数名: void func(int i)
    抛出异常的类型: int
                        -1 ==> 参数异常
                        -2 ==> 运行异常
                        -3 ==> 超时异常
*/

void func(int i){
    if(i < 0){
        throw -1;
    }
    if(i > 100){
        throw -2;
    }
    if(i == 11){
        throw -3;
    }
    cout <<"run func..." << endl;
}

void myfunc(int i){
    try{
        func(i);
    }
    catch(int i){
        switch(i){
            case -1:
                throw exception(-1,"invalid parameter");
                break;
            case -2:
                throw exception(-2,"runtime exception");
                break;
            case -3:
                throw exception(-3,"timeout exception");
                break;
        }
    }
}

int main(){
    try{
        myfunc(11);
    }
    catch(const exception& e){  //务必注意上一层catch抛出的类型
        cout << "exception info:" << endl;
        cout << "   id:" << e.id() << endl;
        cout << "   description:" << e.description() << endl;
    }
    catch(const base& e){
        cout << "catch(const base& e)" << endl;
    }
    return 0;
}

打印结果:

exception info:
        id:-3
        description:timeout exception

c++标准库中提供了实用异常类族 标准库中的异常都是从exception类派生的 exception类有两个主要的分支

logic_error 常用于程序中的可避免的逻辑错误 runtime_error 常用于程序中无法避免的恶性错误

C++中的异常处理教程(下)

编程实验:标准库中的异常使用

代码一:array.h


#ifndef _array_h_
#define _array_h_

#include     //注意该头文件

using namespace std;

template < typename t, int n >
class array{
    t m_array[n];
    public:
        int length() const;
        bool set(int index, t value);
        bool get(int index, t& value);
        t& operator[] (int index);
        t operator[] (int index) const;
        virtual ~array();
};

template < typename t, int n >
int array::length() const{    //注意加const
    return n;
}

template < typename t, int n >
bool array::set(int index, t value){
    bool ret = (0 <= index) && (index < n);
    if( ret ){
        m_array[index] = value;
    }
    return ret;
}

template < typename t, int n >
bool array::get(int index, t& value){
    bool ret = (0 <= index) && (index < n);
    if( ret ){
        value = m_array[index];
    }
    return ret;
}

template < typename t, int n >
t& array::operator[] (int index){
    if( (0 <= index) && (index < n) ){
        return m_array[index];
    }
    else{
        throw out_of_range("t& array::operator[] (int index)");//设置异常处理
    }
}

template < typename t, int n >
t array::operator[] (int index) const{
    if( (0 <= index) && (index < n) ){
        return m_array[index];
    }
    else{
        throw out_of_range("t array::operator[] (int index) const");
    }
}

template < typename t, int n >
array::~array()
{
}

#endif

代码二:heaparray.h

#ifndef _heaparray_h_
#define _heaparray_h_

#include 

using namespace std;

template < typename t >
class heaparray{
    private:
        int m_length;
        t* m_pointer;

        heaparray(int len);
        heaparray(const heaparray& obj);
        bool construct();
    public:
        static heaparray* newinstance(int length); 
        int length() const;
        bool get(int index, t& value);
        bool set(int index ,t value);
        t& operator [] (int index);
        t operator [] (int index) const;
        heaparray& self();
        const heaparray& self() const;
        ~heaparray();
};

template < typename t >
heaparray::heaparray(int len){
    m_length = len;
}

template < typename t >
bool heaparray::construct(){   
    m_pointer = new t[m_length]; 
    return m_pointer != null;
}

template < typename t >
heaparray* heaparray::newinstance(int length){
    heaparray* ret = new heaparray(length);

    if( !(ret && ret->construct()) ) {
        delete ret;
        ret = 0;
    }   
    return ret;
}

template < typename t >
int heaparray::length() const{
    return m_length;
}

template < typename t >
bool heaparray::get(int index, t& value){
    bool ret = (0 <= index) && (index < length());

    if( ret ){
        value = m_pointer[index];
    }

    return ret;
}

template < typename t >
bool heaparray::set(int index, t value) {
    bool ret = (0 <= index) && (index < length());

    if( ret )
    {
        m_pointer[index] = value;
    }  
    return ret;
}

template < typename t >
t& heaparray::operator [] (int index){
    if( (0 <= index) && (index < length()) ){
        return m_pointer[index];
    }
    else{
        throw out_of_range("t& heaparray::operator [] (int index)");//调用标准库异常out_of_range
    }
}

template < typename t >
t heaparray::operator [] (int index) const{
    if( (0 <= index) && (index < length()) ){
        return m_pointer[index];
    }
    else{
        throw out_of_range("t heaparray::operator [] (int index) const");
    }
}

template< typename t >
heaparray& heaparray::self(){
    return *this;
}

template < typename t >
const heaparray& heaparray::self() const{
    return *this;
}

template < typename t >
heaparray::~heaparray(){
    delete[]m_pointer;
}

#endif

代码三:65-3.cpp

#include
#include
#include "array.h"
#include"heaparray.h"

using namespace std;

void testarray(){
    array a;
    for(int i = 0;i < a.length();++i){
        a[i] = i;
    }
    for(int i = 0;i < a.length();++i){
        cout << a[i] << endl;
    }
}

void testheaparray(){
    heaparray* pa = heaparray::newinstance(5);
    if(pa != null){
        heaparray& array = pa->self();
        for(int i = 0;i < array.length();++i){
            array[i] = i;
        }
        for(int i = 0;i < array.length();++i){
            cout << array[i] << endl;
        }
    }
    delete pa;
}

int main(){
    try{
        testarray();
        cout << endl;
        testheaparray();
    }
    catch(...){
        cout << "exception" << endl;
    }
    return 0;
} 

二、总结

catch语句块可以抛出异常 异常的类型可以是自定义类类型 赋值兼容性原则在异常匹配中依然适用 标准库中的异常都是从exception类派生出来的