重学C++系列之异常

一、什么是异常

       异常一般是指程序运行期发生的非正常情况。异常一般是不可预测的,如:内存不足,打开文件失败,数组越界,范围溢出等。

        在某段程序发生无法继续正常执行的情况时,C++允许程序进行所谓抛出异常(有时候也称为吐出异常)的行为。

二、异常的特性

        异常从触发点开始向外传播,直到被捕获(有时候也被称为吞下异常),如果没有被捕获程序就终止。

三、怎么处理异常

        异常处理的核心思想是,把功能模块代码与系统中可能出现的错误代码分离开来,以此来达到代码组织更美观,逻辑上更清晰,并且同时从根本上来提高我们软件系统长时间稳定运行的可靠性。

// 语法简单示例:


try
{
    // 执行可能抛出异常的代码
    int fd = open("1.txt", O_RDONLY);
    if(fd == -1)
    {
        throw -1;
    }
}
catch(int i)    // 捕获整形异常
{
    cout << i << endl;
}
catch(...)    // 捕获其他异常
{
    cout << "other execption" << endl;
}

四、异常安全问题

        1、由于抛出的异常只要找到匹配的catch就直接跳到catch块执行,没有找到对应catch的函数就不会继续执行,这样会导致函数的执行流程很乱,可能会导致一些问题。

        2、构造函数完成对象的构造和初始化,最好不要在构造函数中抛出异常,否则可能会导致对象不完整或者没有完全初始化。

        3、析构函数主要完成资源的清理,最好不要在析构函数中抛出异常,否则可能导致内存泄漏。

五、案例

        1、异常最简单使用

#include <iostream>

using namespace std;

int main()
{
    // 计算两个整形数之间的除法
    cout << "please input a, b " << endl;
    int a, b;
    while(1)
    {
        cin >> a >> b;

        try
        {         
            if(b == 0)
            {
                throw -1;   // 抛出整型异常
            }
            else
            {
                cout << a << " / " << b << " = " << (float)a/b << endl;
                break;
            }
        }
        catch(int e)    // 捕获整型异常
        {
            cout << "b == 0 is illegal, please input a, b again" << endl;
            continue;
        }
    }
    cout << "sucess" << endl;



    return 0;
}

        2、异常类使用

        声明一个异常类作为基类,然后其派生类为异常的具体类型,采用多态的思想来解决捕获单个不同类型的异常。

#include <iostream>

using namespace std;


// 异常基类
class Exception
{
protected:
    string _errmsg; // 错误信息
    int _id;     // 错误码

public:
    Exception(const string &msg = string(), int id = 0)
    {
        _errmsg = msg;
        _id = id;
    }

    virtual void handle() = 0;

};

// 数据处理异常类
class DataException: public Exception
{
public:
    DataException(const string &msg = string(), int id = 1):Exception(msg, id)
    {

    }

    void handle()
    {
        cout << "DataException" << endl;
        cout << "errmsg:" << _errmsg << " id: " << _id << endl;
    }
};

// 网络异常类
class HttpException: public Exception
{
public:
    HttpException(const string &msg = string(), int id = 2):Exception(msg, id)
    {

    }

    void handle()
    {
        cout << "HttpException" << endl;
        cout << "errmsg:" << _errmsg << " id: " << _id << endl;
    }
};


int main()
{
    try
    {
        throw DataException("data is illegal", 1);
    }
    catch(Exception &e)
    {
       e.handle();
    }
    
    cout << endl;
    try
    {
        throw HttpException("network disconnect", 2);
    }
    catch(Exception &e)
    {
       e.handle();
    }

    return 0;
}

六、总结

        异常可以使用自己声明的,也可以使用C++提供的。异常把功能模块代码和错误处理代码分开,使逻辑更加清晰,但是使用异常也会带来一些问题,需要注意。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值