• 【C++ Exceptions】Catch exceptions by reference!


    catch exceptions

    写一个catch子句时必须指明异常对象是如何传递到这个子句来的,三种方式:

    1. by pointer
    2. by value
    3. by reference

    接下来比较它们使用时会出现的问题,以说明最好的选择是by reference。

    catch by pointer

    • 无需复制对象,所以效率高;
    • 如果未使用全局或静态对象,则可能出现“我捕捉到一个指针,它却指向一个已经不存在的对象”的问题;
    • 4个标准异常:bad_malloc(当operator new无法满足内存需求时被抛出),bad_cast(当对一个reference施行dynamic_cast失败时发出),bad_typeid(当dynamic_cast被实施于一个null指针时发出),bad_exception(适用于未预期的异常情况) ——都是对象,不是指向对象的指针。

    catch by value

    • 解决上述问题;
    • 需要复制两次
    • 会引起切割(slicing)问题
      派生类的异常对象被捕捉,并且被视为基类的异常对象,那么派生类就被切割掉了,如:
    class exception		//标准异常类
    {
    public:
    	virtual const char* what() throw();
    };
     
    class runtime_error://标准异常类
    	public exception{...}
    	
    class Validation_error	//重新定义的异常类
    	public exception
    	{
    	public:
    		virtual const char* what() throw();	
    	}
     
    void someFunction()
    {
    	...
    	if(失败)
    		throw Validation_error();
    }	
     
    void doSomething()
    {
    	try{
    		someFunction();
    	}
    	catch(exception ex)
    	{
    		cerr << ex.what();	//调用的exception::what
    	}						//而不是Validation_error::what
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    调用的是基类的what函数——即使抛出的异常属于Validation_error类型,而Validation_error重新定义了虚函数。

    catch by reference

    • 解决上述问题:即不会发生对象删除的问题、避开异常对象的切割问题;
    • 异常对象只会被复制一次
    void doSomething()
    {
    	try{
    		someFunction();
    	}
    	catch(exception& ex)	//catch by reference
    	{
    		cerr << ex.what();	
    			//调用的是Validation_error::what
    			// 而非exception::what
    	}						
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    总结

    最佳的捕捉异常方式:catch by reference
    (catch子句内增加一个&符号)

  • 相关阅读:
    无限边界:现代整合安全如何保护云
    运行stable-diffusion-xl-refiner-1.0遇到version `GLIBCXX_3.4.29‘ not found的问题
    uniapp 条件编译 APP 、 H5 、 小程序
    WPS文件转PDF文件怎么转?建议看看这些方法
    4个工作学习必备的工具,请不要错过
    避免按钮重复点击的小工具bimianchongfu.queren()
    Redis从入门到放弃(1):安装配置
    opensuse server连接wifi
    Linux--makefile
    安装2023最新版PyCharm来开发Python应用程序
  • 原文地址:https://blog.csdn.net/weixin_49347928/article/details/132976516