首页 > 代码库 > C++异常处理

C++异常处理

技术分享

技术分享

#include <iostream>
#include <string>

using namespace std;

double divide(double a, double b)
{
    const double delta = 0.000000000000001;
    double ret = 0;
    
    if( !((-delta < b) && (b < delta)) )
    {
        ret = a / b;
    }
    else
    {
        throw 0;//抛出异常
    }
    
    return ret;
}

int main(int argc, char *argv[])
{    
    try
    {
        double r = divide(1, 0);//divide除数为0时抛出异常,如果不try catch 程序会异常终止
            
        cout << "r = " << r << endl;
    }
    catch(...)//...表示捕获任何类型的异常 这里divide得异常时 int类型的
    {
        cout << "Divided by zero..." << endl;
    }
    
    return 0;
}

  

技术分享

技术分享

技术分享

技术分享

 

#include <iostream>
#include <string>

using namespace std;


//try 中捕获的异常类型必须跟 cath中的异常类型严格匹配!不进行任何类型转换
//类类型的异常 适用赋值兼容性原则,子类的异常会匹配父类的catch语句
void Demo1()
{
    try
    {   
        throw ‘c‘;
    }
    catch(char c)
    {
        cout << "catch(char c)" << endl;
    }
    catch(short c)
    {
        cout << "catch(short c)" << endl;
    }
    catch(double c)
    {
        cout << "catch(double c)" << endl;
    }
    catch(...)//...语句必须放在最后,捕捉未被catch的任意类型的异常
    {
        cout << "catch(...)" << endl;
    }
}

void Demo2()
{
    throw string("D.T.Software");//const char *cs类型
}

int main(int argc, char *argv[])
{    
    Demo1();
    
    try
    {
        Demo2();
    }
    catch(char* s)
    {
        cout << "catch(char *s)" << endl;
    }
    catch(const char* cs)
    {
        cout << "catch(const char *cs)" << endl;
    }
    catch(string ss)
    {
        cout << "catch(string ss)" << endl;
    }
    
    return 0;
}

  

技术分享

 

 技术分享

catch语句抛出异常,目的是为了重新定义异常信息:

技术分享

#include <iostream>
#include <string>

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[])
{
    // Demo();
    
    try
    {
        MyFunc(11);
    }
    catch(const char* cs)
    {
        cout << "Exception Info: " << cs << endl;
    }
    
    return 0;
}

  

技术分享

匹配父类异常的catch必须放在最后,否则捕获子类异常的函数将永远不会被执行

#include <iostream>
#include <string>

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(int argc, char *argv[])
{
    try
    {
        MyFunc(11);
    }
    //引用作为参数,可以提高程序的执行效率,应为类类型的实参会经过拷贝构造产生一个形参
    //直接传递引用可以跳过拷贝构造,提高效率
    catch(const Exception& e)
    {
        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;
}

  技术分享

    //引用作为参数,可以提高程序的执行效率,应为类类型的实参会经过拷贝构造产生一个形参
    //直接传递引用可以跳过拷贝构造,提高效率

技术分享

技术分享

技术分享

 

 


 

C++异常处理