第十课 数据结构C++异常简介

本文学习自 狄泰软件学院 唐佐林老师的 数据结构课程


为什么在数据结构的课程中插入C++异常课程?

答:我们最终的目的是创建一个可复用的C++数据结构代码库,此代码库除了依赖C++模板技术之外,还依赖C++异常处理机制

异常:可预见的异常情况,错误是不可预见的

C++内置了异常处理的语法元素try…catch

  • try语法处理正常代码逻辑分支
  • catch语法处理异常代码逻辑分支
  • try语句中的异常由对应的catch语句处理

在这里插入图片描述

在这里插入图片描述

C++通过throw语句抛出异常信息 : throw 0;

C++异常处理分析

  • throw抛出的异常必须被catch处理
  • 当前函数能够处理异常,程序继续往下执行
  • 当前函数无法处理异常,则函数停止执行,并返回
    在这里插入图片描述

实验1:当前函数没有做异常处理,程序会立即停止

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;   // 产生除 0 异常
    }

    return ret;
}
	
int main()
{
    cout << "main() begin" << endl;
    
    //用 1 除以 0  一定会报异常,当前函数没有做异常处理,程序会立即停止,仅仅输出了 "main() begin
    double c = divide(1, 0);
    
    cout << "main() end" << endl;
    
    return 0;
}

在这里插入图片描述

实验 2:添加异常处理

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;   // 产生除 0 异常
    }

    return ret;
}
	
int main()
{
    cout << "main() begin" << endl;
    
    try
    {
    	// 1 除以 0 产生异常  由 try catch 异常处理 进行处理。处理完之后 继续正常的执行语句
        double c = divide(1, 0);
    }
    catch(...)
    {
        cout << "Divided by zero..."  << endl;
    }
    
    cout << "main() end" << endl;
    
    return 0;
}

在这里插入图片描述

实验3 :异常处理时,不会继续执行 try中异常位置之后的代码,直接到catch中。

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;   // 产生除 0 异常
    }

    return ret;
}
	
int main()
{
    cout << "main() begin" << endl;
    
    try
    {
    	// 1 除以 0 产生异常  由 try catch 异常处理 进行处理。直接到catch  不会执行try中的打印语句
        double c = divide(1, 0);
        
        cout << "c = " << c << endl;
    }
    catch(...)
    {
        cout << "Divided by zero..."  << endl;
    }
    
    cout << "main() end" << endl;
    
    return 0;
}

在这里插入图片描述

同一个try语句可以跟上多个catch语句

  • catch语句可以定义具体处理的异常类型
  • 不同类型的异常由不同的catch语句负责处理
  • try语句中可以抛出任何类型的异常
  • catch(…)用于处理所有类型的异常
  • 任何异常都只能被捕获(catch)一次

异常处理的匹配规则:
异常抛出后,至上而下严格匹配每一个catch语句处理的类型,而且在异常处理匹配时,不进行任何的类型转换。(和函数调用不同,不进行默认类型转换)

在这里插入图片描述

实验3 ://异常的类型的严格匹配,这里处理

void Demo1()
{
    try
    {
        throw 'c';
    }
    catch(int i)
    {
        cout << "catch(int i)" << endl;
    }
    catch(double d)
    {
        cout << "catch(double d)" << endl;
    }
    catch(char c)//异常的类型的严格匹配,这里处理
    {
        cout << "catch(char i)" << endl;
    }
}




int main()
{
    Demo1();

	return 0;
}

在这里插入图片描述

实验4 : catch(…)可以匹配任何异常,但是如果前面已经处理了异常,就不会走 catch(…)。

void Demo2()
{
	//抛出  字符串字面常量 异常  类型为  const char*
    throw "D.T.Software";
}

int main()
{

    try
    {
        Demo2();//字符串异常
    }
    catch(char* c)
    {
        cout << "catch(char* c)" << endl;
    }
    catch(const char* cc)//这里匹配 字符串字面常量
    {
        cout << "catch(char* cc)" << endl;
    }
    catch(...)//虽然可以匹配任何异常,但是前面已经处理了异常,所以不会走到这里。
    {
        cout << "catch(...)" << endl;
    }

	return 0;
}

在这里插入图片描述

实验5

void Demo2()
	{
	    throw 0.0001;
	}

int main()
{

    try
    {
        Demo2();//字符串异常
    }
    catch(char* c)
    {
        cout << "catch(char* c)" << endl;
    }
    catch(const char* cc)//这里匹配 字符串字面常量
    {
        cout << "catch(char* cc)" << endl;
    }
    catch(...)//可以匹配任何异常
    {
        cout << "catch(...)" << endl;
    }

	return 0;
}

在这里插入图片描述

小结:

  • C++中直接支持异常处理的概念
  • try…catch…是c++中异常处理的专用语句
  • try语句处理正常代码逻辑,catch语句处理异常代码逻辑
  • 同一个try语句可以跟上多个catch语句
  • 异常处理必须严格匹配,不进行任何的类型转换

补充:

C++函数后面加关键字throw(something)限制,是对这个函数的异常安全作出限制;这是一种异常规范,只会出现在声明函数时,表示这个函数可能抛出任何类型的异常。

void fun() throw();//表示fun函数不允许抛出任何异常,即fun函数是异常安全的。

void fun() throw(...);//表示fun函数可以抛出任何形式的异常。

void fun() throw(exceptionType); // 表示fun函数只能抛出exceptionType类型的异常。

void GetTag() throw(int); // 表示只抛出int类型异常
void GetTag() throw(int,char);  // 表示抛出in,char类型异常
void GetTag() throw(); // 表示不会抛出任何类型异常
void GetTag() throw(...);    // 表示抛出任何类型异常
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ma浩然

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值