序
见到cm中由于在catch中throw没catch引起的crash, 总结一下.
实验
// @file testcase05101520.cpp : Defines the entry point for the console application.
// @brief test throw on catch
// @note 对于描述为throw的c++的接口定义, 必须try-catch住.
// 对于接口是否会抛出异常, 可以在接口描述中叙述, 也可以在接口定义中用throw描述
// e.g. void CMyExp::DoThrowA(); void CMyExp::DoThrowB() throw(exception)
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <exception>
using namespace std;
class CMyExp : public std::exception {
public:
CMyExp() {m_str_what = "MyExp";}
virtual ~CMyExp() {}
void setWhat(const char* pszWhat) {m_str_what = ((NULL != pszWhat) ? pszWhat : "MyExp");}
const char* what () const throw () {
return m_str_what.c_str();
}
// @fn DoThrowA
// @brief 接口中会抛出异常的例子A
// @param NULL
// @note 会抛出 exception e异常
// @return void
void DoThrowA() {
exception e("DoThrowA");
throw e;
}
// @fn DoThrowB
// @brief 接口中会抛出异常的例子B
// @param NULL
// @return void
void DoThrowB() throw(exception) {
exception e("DoThrowA");
throw e;
}
private:
std::string m_str_what;
};
void fnTryCatch1_doTask();
void fnTryCatch2_tryAgain();
int main(int argc, char* argv[])
{
fnTryCatch1_doTask();
system("pause");
/** run result
e.what = throw on fnTryCatch1_doTask
e.what = throw on fnTryCatch2_tryAgain
try again ok
*/
return 0;
}
void fnTryCatch1_doTask()
{
CMyExp e;
try {
// do something, when error, throw
e.setWhat("throw on fnTryCatch1_doTask");
throw(e);
}
catch (exception& e) {
printf("e.what = %s\n", e.what());
// 可以在这里进行try-catch嵌套
// 也可以将try-catch写入另外的函数fnB, 整洁些, 然后在catch中调用那个函数fnB
// 总之, 一个try(throw)必须要有一个catch, 否则throw或运行时其他异常(e.g. div0)没人接住,传到系统程序就报错了.
// 这样, 在catch中throw也是可以正常运行的
fnTryCatch2_tryAgain();
}
}
void fnTryCatch2_tryAgain()
{
CMyExp e;
try {
// do something, when error, throw
// e.g. mongo c++ interface, maybe throw when call it
// so when call a c++ interface declare indicate throw, we will try catch it
e.setWhat("throw on fnTryCatch2_tryAgain");
throw(e);
}
catch (exception& e) {
printf("e.what = %s\n", e.what());
printf("try again ok\n");
}
}