【C++】异常

06-02 215阅读

  🌈个人主页:秦jh_-CSDN博客
🔥 系列专栏:https://blog.csdn.net/qinjh_/category_12575764.html?spm=1001.2014.3001.5482

 【C++】异常​ 

目录

C语言传统的处理错误的方式

C++异常概念 

异常的使用 

异常的抛出和捕获

在函数调用链中异常栈展开匹配原则 

 自定义异常体系

 异常的重新抛出

异常安全 

异常规范 

 C++标准库的异常体系

异常的优缺点 

C++异常的优点: 

C++异常的缺点:


前言

    💬 hello! 各位铁子们大家好哇。

             今日更新了C++异常的相关内容

    🎉 欢迎大家关注🔍点赞👍收藏⭐️留言📝

C语言传统的处理错误的方式

传统的错误处理机制:

  1.  终止程序,如assert,缺陷:用户难以接受。如发生内存错误,除0错误时就会终止程序。
  2. 返回错误码,缺陷:需要程序员自己去查找对应的错误。如系统的很多库的接口函数都是通 过把错误码放到errno中,表示错误

C++异常概念 

异常是一种处理错误的方式,当一个函数发现自己无法处理的错误时就可以抛出异常,让函数的 直接或间接的调用者处理这个错误。 

  • throw: 当问题出现时,程序会抛出一个异常。这是通过使用 throw 关键字来完成的。
  • catch: 在您想要处理问题的地方,通过异常处理程序捕获异常.catch 关键字用于捕获异常,可以有多个catch进行捕获。
  • try: try 块中的代码标识将被激活的特定异常,它后面通常跟着一个或多个 catch 块。 

    如果有一个块抛出一个异常,捕获异常的方法会使用 try 和 catch 关键字。try 块中放置可能抛 出异常的代码,try 块中的代码被称为保护代码。 

    异常的使用 

    异常的抛出和捕获

    1. 异常是通过抛出对象而引发的,该对象的类型决定了应该激活哪个catch的处理代码。
    2.  被选中的处理代码是调用链中与该对象类型匹配且离抛出异常位置最近的那一个。
    3.  抛出异常对象后,会生成一个异常对象的拷贝,因为抛出的异常对象可能是一个临时对象, 所以会生成一个拷贝对象,这个拷贝的临时对象会在被catch以后销毁。(这里的处理类似 于函数的传值返回)
    4.  catch(...)可以捕获任意类型的异常,问题是不知道异常错误是什么。
    5. 实际中抛出和捕获的匹配原则有个例外,并不都是类型完全匹配,可以抛出的派生类对象, 使用基类捕获。

    在函数调用链中异常栈展开匹配原则 

    1. 首先检查throw本身是否在try块内部,如果是再查找匹配的catch语句。如果有匹配的,则调到catch的地方进行处理。
    2. 没有匹配的catch则退出当前函数栈,继续在调用函数的栈中进行查找匹配的catch。
    3. 如果到达main函数的栈,依旧没有匹配的,则终止程序。上述这个沿着调用链查找匹配的 catch子句的过程称为栈展开。所以实际中我们最后都要加一个catch(...)捕获任意类型的异 常,否则当有异常没捕获,程序就会直接终止。
    4. 找到匹配的catch子句并处理以后,会继续沿着catch子句后面继续执行。 

    举例:

    【C++】异常【C++】异常

    如上图,有两个地方捕获异常,此时就会调用离最近的一个,并且处理完catch语句后,会继续往后执行。 

     自定义异常体系

    实际使用中很多公司都会自定义自己的异常体系进行规范的异常管理,因为一个项目中如果大家 随意抛异常,那么外层的调用者基本就没办法玩了,所以实际中都会定义一套继承的规范体系。 这样大家抛出的都是继承的派生类对象,捕获一个基类就可以了 

    class Exception
    {
    public:
    	Exception(const string& errmsg, int id)
    		:_errmsg(errmsg)
    		, _id(id)
    	{}
    	virtual string what() const
    	{
    		return _errmsg;
    	}
    protected:
    	string _errmsg;
    	int _id;
    };
    class SqlException : public Exception
    {
    public:
    	SqlException(const string& errmsg, int id, const string& sql)
    		:Exception(errmsg, id)
    		, _sql(sql)
    	{}
    	  
    	virtual string what() const
    	{
    		string str = "SqlException:";
    		str += _errmsg;
    		str += "->";
    		str += _sql;
    		return str;
    	}
    private:
    	const string _sql;
    };
    class CacheException : public Exception
    {
    public:
    	CacheException(const string& errmsg, int id)
    		:Exception(errmsg, id)
    	{}
    	virtual string what() const
    	{
    		string str = "CacheException:";
    		str += _errmsg;
    		return str;
    	}
    };
    class HttpServerException : public Exception
    {
    public:
    	HttpServerException(const string& errmsg, int id, const string& type)
    		:Exception(errmsg, id)
    		, _type(type)
    	{}
    	virtual string what() const
    	{
    		string str = "HttpServerException:";
    		str += _type;
    		str += ":";
    		str += _errmsg;
    		return str;
    	}
    private:
    	const string _type;
    };
    void SQLMgr()
    {
    	srand(time(0));
    	if (rand() % 7 == 0)
    	{
    		throw SqlException("权限不足", 100, "select * from name = '张三'");
    	}
    	else
    	{
    		cout 
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

相关阅读

目录[+]

取消
微信二维码
微信二维码
支付宝二维码