【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
}

调用的是基类的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
	}						
}

总结

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

你可能感兴趣的:(C++进阶,c++,笔记,开发语言)