六十五课 C++中的异常处理(下)

这节课我们来深入了解下C++中的异常处理

1、catch语句块可以抛出异常

try
{
  func()//抛出异常int类型
}
catch(int i)
{
  throw i; //这里抛出的异常必须在外层的try...catch被捕获
}
catch(...)
{
  throw;
}

2、问题:为什么要在catch重新抛出异常?

假如我们使用第3方库,他会抛出异常类型为int,但是我们在自己创建的私有库中需要统一的使用异常类型,这样我们就需要重新解释这个异常了。如下图

示例:异常的重新解释 

#include <iostream>
#include <string>

using namespace std;

/*
    假设: 当前的函数式第三方库中的函数,因此,我们无法修改源代码
    
    函数名: 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()
{
  try
  {
    MyFunc(11);
  }
  catch(const char* cs)
  {
   cout << "Exception Info: " << cs << endl;
  }
 
    return 0;
}

打印结果

通过这个示例可以看出,我们模拟的第3方库只会抛出int类型的异常,但是我们不知道这个异常具体的含义,所以我们可以利用catch重新抛出异常,这样我们就可以一目了然了。

3、异常可以自定义类类型

  • 异常自定义的类型可以是自定义类类型
  • 对于类类型异常的匹配依旧是至上而下严格匹配
  • 赋值兼容原则在异常匹配中依然适用
  • 一般而言
  • 匹配子类异常的catch放在上部
  • 匹配父类异常的catch放在下部
  • 在定义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()
{
  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;
}

打印结果

猜你喜欢

转载自blog.csdn.net/qq_34862658/article/details/81947857