c++ - rethrow a exception gotchas

As in my prevoius example in  java - common practice to rethrow exceptions, we have seen that it is always good to rethrow an new exception with the old exception as its inner exception, and it is not too bad after to just throw the exception that you have just catched (only you loose the information that the original exception has).

 

in C++, there is  a special syntax to rethrow the exception that has been caught. which is just call "throw" without any argument, here is what you do 

 

try {
  // statements.
} catch (const exception& ex_)  {
  throw;
}

 because of the "const reference &" syntax in the code above. 

 

Since not all C++ classes has the necessary call stack support,  we might not be able to show every clearly the major diference in terms of the call stack. 

 

class UnsupportedException : public exception {
public:
	 const exception * const innerException() {
		return _innerException;
	}

	UnsupportedException(const char*  message_, const exception * const innerException_) : exception(message_), message(message_), _innerException(innerException_) {
	}

	UnsupportedException(const UnsupportedException& rhs) : 
		exception(rhs.message), message(rhs.message), _innerException(rhs._innerException)
	{
	}
	/** one thing is missing which is called delegaing constructor */
	virtual const char * what() { 
		return ((const UnsupportedException *) this)->what();
	}

	virtual const char * what() const { 
		char* b = new char[100];
		strcpy(b, message);
		if (_innerException != NULL) { 
			strcat(b, "cause by \n");
			strcat(b, _innerException->what());
		}
		return b;
	}



private:
	const char * message;
	const exception *  const _innerException;
};


void generateException() 
{
	const UnsupportedException exc = UnsupportedException("not implemented 'generateException'", new exception("Inner exception"));
	throw exc;
}


void rethrowException() 
{
	try {
		generateException();
	} catch (exception& ex_) { 
		throw;
	}
}

void rethrowDestroyOriginalInfo() { 
	try { 
		generateException();
	} catch (const exception & ex_)  {
		throw ex_;
	}
}


void rethrowExceptionWithInnerException() 
{
	try {
		generateException();
	} catch (exception& ex_) { 
		throw UnsupportedException("wrapped new UnsupportedException", new UnsupportedException(dynamic_cast<const UnsupportedException &>(ex_)));
	}
}


int _tmain(int argc, _TCHAR* argv[])
{
	try { 
		rethrowException();
	}
	catch (const UnsupportedException & ex_) {
		cout <<  "in catch (const exception & ex_)" << endl;
		const char * what = ex_.what();
		cout << what << endl;
	}

	cout <<  "============================ " << endl;

	try { 
		rethrowDestroyOriginalInfo();
	}
	catch (const UnsupportedException & ex_) {
		cout <<  "in catch (const exception & ex_)" << endl;
		const char * what = ex_.what();
		cout << what << endl;
	}
	catch (const exception & ex_)  {
		cout <<  "in const exception & ex_" << endl;
		const char * what = ex_.what();
		cout << what << endl;
	}

	cout <<  "============================ " << endl;

	try { 
		rethrowExceptionWithInnerException();
	}
	catch (const UnsupportedException & ex_) {
		cout <<  "in catch (const exception & ex_)" << endl;
		const char * what = ex_.what();
		cout << what << endl;
	}
	catch (const exception & ex_)  {
		cout <<  "in const exception & ex_" << endl;
		const char * what = ex_.what();
		cout << what << endl;
	}
	return 0;
}

 

and the output of the running the above program is like this:  

 

in catch (const exception & ex_)
not implemented 'generateException'cause by
Inner exception
============================
in const exception & ex_
not implemented 'generateException'
============================
in catch (const exception & ex_)
wrapped new UnsupportedExceptioncause by
not implemented 'generateException'cause by
Inner exception
 

As you can see, with the "throw;" the standard way of rethrowing excpetion, it has the correct error messages and with the "throw ex;", the real type of exception may be lost in the catch handler (you can see the second output", the third is what we try to replicate for the c# or java style of throwing exception - which to be honest, I am not sure if that is indeed what we really what we wantted to do in C++;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值