C++学习笔记13--异常处理

异常处理

    什么是异常:不常发生但无法避免。

      返回错误码

      设置errno全局变量

      抛出异常

    捕获异常:

      用Try{}把可能发生异常的代码包起来紧跟其后用若干个(至少一个)catch(类型 e){}来捕获指定类型的异常并处理,处理后程序从最后一个catch块后继续运行。

      抛出异常:throw 数据;

    被Throw拋出的异常数据不受作用范围的限制,直到被捕获被处理为止,因此在捕获时可以通过引用来访问异常数据。即使已经被处理的异常数据,也可以用一个不带数据的throw重新抛出。

    如果抛出的异常没有被捕获处理,系统会调用terminate()函数终止程序。set_terminate(fun)可以指定在terminate时自动调用func函数。

    异常传递机制:从throw开始离开正常执行流程,在本函数内找有没有包含它的try{}块,如果有依次查找它的catch块直到第一个类型匹配的为止进入这个catch块执行处理,之后从最后一个catch块之后继续执行;如果没有包含它的try{}块或者没有类型匹配的catch块,异常数据继续传递到上层函数(调用它的那个函数)中重复这个过程,如果直到Main函数还没有处理,就会传递给内核,系统就会调用terminate终止程序

    多个catch块如果同时有父类类型和子类类型,应该把子类类型放在前面,如果有一个是catch(...),它必须放在最后。

#include<iostream>
using namespace std;
#include<string>

void f1()
{
    try{
        cout<<"1--int\n2--double\n0--return\n";
        int n;
        cin>>n;
        if(n==1) throw 1;
        if(n==2) throw 2.2;
        if(n==0) return;
        throw string("error");
    }
    catch(long e){cout<<"long "<<e<<endl;}
    catch(double e){cout<<"double "<<e<<endl;}
    cout<<"----endl of f1----"<<endl;
}
void f2()
{
try{
        f1();
        cout<<"----in f2----"<<endl;
    }
    catch(int e){cout<<"int "<<e<<endl;}
    cout<<"----end of f2----"<<endl;
}

int main()
{
    try{
        f2();
    }
    catch(...) {cout<<"发生异常"<<endl;}
    cout<<"我还会回来的"<<endl;
    system("pause");
}

    异常申明:一个函数可以声明自己可能抛出哪些类型的异常,格式为

      返回类型 函数名(参数表) throw(异常类型列表);

      int func(int a[],int idx) throw(double,int,string);

    如果在函数内部抛出了不在列表中的异常,则会引发意外。unexpected 可以通过set_unexpected(func)来设置遇到意外的情况时调用func来设置遇到意外情况时调用func.没有异常声明表示可能抛出任何类型的异常,空异常列表表示不会抛出异常

#include<iostream>
using namespace std;
#include<exception>

void f1(int n)throw(int,double)
{
    try{
    if(n==1) throw 123;
    if(n==2) throw 4.5;
    throw "out of range";
    }
    catch(int e){
     cout<<"catch "<<e<<" in f1"<<endl;
     if(e>100) throw;//重新抛出当前异常数据
    }
}
void func(){cout<<"异常类型不在列表中"<<endl;}

int main(int argc,char* argv[])
{//argument参数,cont数量,vector不定长数组
    set_unexpected(func);
    try{
        cout<<"argc="<<argc<<endl;
        f1(argc);
    }
    catch(int e){cout<<"int "<<e<<endl;}
    catch(double e){cout<<"double "<<e<<endl;}
    //catch(...){cout<<"exception"<<endl;}
    system("pause");
}

    标准异常:exception类,#include<exception>

    定义子类覆盖父类的虚函数时,异常声明的内容不能超出父类中异常声明的内容

    标准库中抛出的异常类型都是exception的子类

    自己定义异常类型一般继承exception类,覆盖const char* what() const throw()函数,返回一个字符串,描述发生了什么异常

    

#include<iostream>
using namespace std;
#include<exception>
#include<new>
#include<cstdio>

class A{//数组类
    int *p;
    int len;
public:
    explicit A(int n) throw(){
    p = new (nothrow) int[n];
    len = n;
    }
    int& operator[](int index){
        if(index<0) throw NegIndex(index);
        if(index>=len) throw OutofRange(index);
        if(p==NULL) throw MemoryException();
        return p[index];
    }
    class NegIndex : public exception{
        int i;
    public:
        NegIndex(int index)throw():i(index){};
        const char* what()const throw(){
            static char buf[100];
            sprintf(buf,"负下标异常%d",i);
            return buf;
        }
    };

    class OutofRange : public exception{
        int i;
    public:
        OutofRange(int index)throw():i(index){};
        const char* what()const throw(){
            static char buf[100];
            sprintf(buf,"越界%d",i);
            return buf;
        }
    };

    class MemoryException : public exception{
    public:
        const char* what()const throw(){
            return "内存不足";
        }
    };
};

int main()
{
    A x(10);
    x[0]  =5,x[3]=10,x[8]=20;
    cout<<x[3]*x[0]*x[8]<<endl;
    cout<<x[-5]<<endl;
    cout<<x[20]<<endl;
    system("pause");
}

  

时间: 2024-12-24 06:48:22

C++学习笔记13--异常处理的相关文章

HTML&CSS基础学习笔记13—无序列表

无序列表 有时我们的工作繁忙,杂事很多,怕忘记,就会把事情一件件列出来,防止忘记. 它们的排列顺序对于我们来说并不重要,可以随意调换,我们将它称为无序列表,HTML里用<ul>标签来表示无序列表,列表里的项目则用<li>标签来表示: 1 2 3 4 5 <ul>     <li></li>     <li></li>     ... </ul> 看一段实例代码: 对于的浏览器显示结果是这样的: 更多内容学习,请

python 学习笔记 6 -- 异常处理

当你的程序中出现某些 异常的 状况的时候,异常就发生了.例如,当你想要读某个文件的时候,而那个文件不存在.或者在程序运行的时候,你不小心把它删除了. 那么如果你是在IDE中运行,一个错误发生,异常会被打引出来,这便是未处理异常:当异常发生时,如果没有代码去关注和处理它,这些异常会传给置在Python中的缺省处理,他会输出一些调试信息并且终止运行.如果是在IDE中,这不是什么大事,但是如果是Python程序运行中的异常,它会导致整个程序终止,对于这些情况可以使用异常来处理. 1.try..exce

Oracle 学习笔记 17 -- 异常处理(PL/SQL)

程序在执行过程中出现异常是正常的,在程序的编写过程中出现异常也是不可避免的.但是要有相应的异常处理的机 制,来保证程序的正常执行.PL/SQL程序执行过程中出现的错误,称为异常.一个优秀的程序都应该能够正确处理 各种出错的情况,并尽可能的从错误中恢复.PL/SQL提供了异常处理机制. 概念: 异常处理(exception)是用来处理正常执行过程中未预料的事件,程序块的异常处理定义的错误和自定义的错误, 由于PL/SQL程序块一旦产生异常而没有指出如何处理时,程序就会异常的终止. 有三种类型的错误

python学习笔记十——异常处理

1.try: command except 错误类型,记录错误信息变量: command finally: command try...finally的用处是无论是否发生异常都要确保资源释放代码的执行.一般来说,如果没有发生错误,执行过try语句块之后执行finally语句块,完成整个流程.如果try语句块发生了异常,抛出了这个异常,此时就马上进入finally语句块进行资源释放处理.如下从几个细节讨论finally的特性. 1).try中的return: 当在try语句块中含有return语句

python 学习笔记 13 -- 常用的时间模块之time

Python 没有包含对应日期和时间的内置类型,不过提供了3个相应的模块,可以采用多种表示管理日期和时间值: *    time 模块由底层C库提供与时间相关的函数.它包含一些函数用于获取时钟时间和处理器的运行时间,还提供了基本解析和字符串格式化工具 *    datetime 模块为日期.时间以及日期时间值提供一个更高层接口.datetime 中的类支持算术.比较和时区配置. *    calendar 模块可以创建周.月和年的格式化表示.它还可以用来计算重复事件.给定日期是星期几,以及其他基

Swift学习笔记(13)--属性 (Properties)

普通属性用var和let即可,本文不做详述 1.延迟存储属性 延迟存储属性是指当第一次被调用的时候才会计算其初始值的属性.在属性声明前使用@lazy来标示一个延迟存储属性. class DataImporter { /* DataImporter 是一个将外部文件中的数据导入的类. 这个类的初始化会消耗不少时间. */ var fileName = "data.txt" // 这是提供数据导入功能 } class DataManager { @lazy var importer = D

springmvc学习笔记(13)-springmvc注解开发之集合类型參数绑定

springmvc学习笔记(13)-springmvc注解开发之集合类型參数绑定 springmvc学习笔记13-springmvc注解开发之集合类型參数绑定 数组绑定 需求 表现层实现 list绑定 需求 表现层实现 map绑定 本文主要介绍注解开发的集合类型參数绑定,包含数组绑定,list绑定以及map绑定 数组绑定 需求 商品批量删除,用户在页面选择多个商品.批量删除. 表现层实现 关键:将页面选择(多选)的商品id,传到controller方法的形參,方法形參使用数组接收页面请求的多个商

Ext.Net学习笔记13:Ext.Net GridPanel Sorter用法

Ext.Net学习笔记13:Ext.Net GridPanel Sorter用法 这篇笔记将介绍如何使用Ext.Net GridPanel 中使用Sorter. 默认情况下,Ext.Net GridPanel中的列都具有排序功能,效果如下: 如果要禁用列排序,需要在列模型中添加一个属性Sortable="false" 客户端排序 排序是对Store的操作.如果我们要在一个Store中加入排序,可以使用下面的配置: <Sorters> <ext:DataSorter P

mybatis学习笔记(13)-查询缓存之二级缓存

mybatis学习笔记(13)-查询缓存之二级缓存 mybatis学习笔记13-查询缓存之二级缓存 二级缓存原理 开启二级缓存 调用pojo类实现序列化接口 测试方法 useCache配置 刷新缓存就是清空缓存 应用场景和局限性 本文主要讲mybatis的二级缓存,二级缓存是mapper级别的缓存,多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的. 二级缓存原理 首先开启mybatis的二级缓存. sqlS

python基础教程_学习笔记13:标准库:一些最爱——sys

标准库:一些最爱 sys sys这个模块让你能够访问与python解释器联系紧密的变量和函数. sys模块中一些重要的函数和变量 函数/变量 描述 argv 命令行参数,包括脚本名称 exit([arg]) 退出当前程序,可选参数为给定的返回值或者错误信息 modules 映射模块名字到载入模块的字典 path 查找模块所在目录的目录名列表 platform 类似sunos5或者win32的平台标识符 stdin 标准输入流--一个类文件对象 stdout 标准输出流--一个类文件对象 stde