C++异常的理解

  • 错误处理技术
    1.终止程序(段错误)
    2.返回错误码
    3.返回合法值
    4.调用一个预先设置的出现错误时调的函数(回调函数)
  • 异常处理
    -当一个函数发现自己无法处理的错误时抛出异常,让函数的调用者直接或间接的处理这个问题。

  • 异常的抛出和捕获
    - 异常是通过抛出对象而引发的,对象的类型决定了应该激活哪个处理代码。
    - 处理代码是与该对象类型匹配且离抛出异常位置最近的哪个
    - 抛出异常后会释放局部存储对象,所处被抛出的对象叶欢给操作系统了,throw会初始化一个抛出特殊的异常对象副本(匿名对象),异常对象由编译管理,对象传给对应的catch处理后撤销。

  • 栈展开
    - 抛出异常的时候,暂停当前函数的执行,开始查找对应的匹配catch。
    - 首先在throw本身是否在团员块内部,如果是查找catch,如果有匹配的,就处理;如果没有匹配的,则退出当前函数栈,继续在调用函数的栈中查找;如果到main函数的栈依旧没有找到匹配的,就终止程序。
  • 异常捕获的匹配规则
    -异常对象类型与catch的类型必须完全匹配
    例外
    1.从非const对象到const对象。
    2.从派生类型到基类类型的转换。
    3.数组转换为指向数组的指针,函数转换为指向函数的指针。
#include <iostream>
#include <string>
using namespace std;

class Exception
{
public :
     Exception(int errId, const char * errMsg)
         : _errId(errId )
         , _errMsg(errMsg )
    {}

     void What () const
    {
          cout<<"errId:" <<_errId<< endl;
          cout<<"errMsg:" <<_errMsg<< endl;
    }
private :
     int _errId ;       // 错误码
     string _errMsg ;  // 错误消息
};

void Func1 (bool isThrow)
{
     // ...
     if (isThrow )
    {
          throw Exception (1, "抛出 Excepton对象" );
    }
     // ...

     printf("Func1(%d)\n" , isThrow);
}

void Func2 (bool isThrowString, bool isThrowInt)
{
     // ...
     if (isThrowString )
    {
          throw string ("抛出 string对象" );
    }
     // ...
     if(isThrowInt )
    {
          throw 7;
    }

     printf("Func2(%d, %d)\n" , isThrowString, isThrowInt );
}

void Func ()
{
     try
    {
          Func1(false );
          Func2(true , true);
    }
     catch(const string& errMsg)
    {
          cout<<"Catch string Object:" <<errMsg<< endl;
    }
     catch(int errId)
    {
          cout<<"Catch int Object:" <<errId<< endl;
    }
     catch(const Exception& e)
    {
          e.What ();
    }
     catch(...)
    {
          cout<<" 未知异常"<< endl;
    }

    printf ("Func()\n");
}

int main()
{
    Func();

    return 0;
}

运行结果如下:这里写图片描述

  • 异常的重新抛出
    有可能单个catch不能完全处理一个异常,在进行一些校正处理后,希望再交给更外层的调用链函数来处理,catch则可以通过重新将异常传递给上层的函数来进行处理。
#include <iostream>
#include <string>
using namespace std;

class Exception
{
public :
     Exception(int errId = 0, const char * errMsg = "" )
         : _errId(errId )
         , _errMsg(errMsg )
    {}

     void What () const
    {
          cout<<"errId:" <<_errId<< endl;
          cout<<"errMsg:" <<_errMsg<< endl;
    }
private :
     int _errId ;       // 错误码
     string _errMsg ;  // 错误消息
};

void Func1 ()
{
     throw string ("Throw Func1 string");
}

void Func2 ()
{
     try
    {
          Func1();
    }
     catch(string & errMsg)
    {
          cout<<errMsg <<endl;
          Exception e (1, "Rethorw Exception");
          throw e ;
          // throw;
          // throw errMsg;
    }
}

void Func3 ()
{
     try
    {
          Func2();
    }
     catch (Exception & e)
    {
          e.What ();
    }
}
int main()
{
    Func3();
    return 0;
}

运行结果如下:
这里写图片描述

  • 异常 构造函数&析构函数
    • 构造函数完成对象的构造和初始化,要保证不在构造函数中抛出异常,否则可能导致对象不完整或没有完全初始化
    • 析构函数 主要完成资源的清理,保证不在析构函数中抛出异常,否则导致资源泄漏(内存泄漏,句柄未关闭等)。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值