以前一直不知道try catch具体应用到什么地方,之前待过的几家公司也看不到有类似的代码。
从网上搜来的,描述try catch优点有下面几点。
1、 把错误处理和真正的工作分开来;
2、 代码更易组织,更清晰,复杂的工作任务更容易实现;
3、 毫无疑问,更安全了,不至于由于一些小的疏忽而使程序意外崩溃了;
4、 由于C++中的try catch可以分层嵌套,所以它提供了一种方法使得程序的控制流可以安全的跳转到上层(或者上上层)的错误处理模块中去。(不同于return语句,异常处理的控制流是可以安
全地跨越一个或多个函数 )。
5、 还有一个重要的原因就是,由于目前需要开发的软件产品总是变得越来越复杂、越来越庞大,如果系统中没有一个可靠的异常处理模型,那必定是一件十分糟糕的局面。
//总结出来就是:减少了判断语句的使用(if),程序更加简洁明了,程序更加健壮。
直到在武侠世界源码里面看到下面的一些代码:
在World的main函数里
有
__ENTER_FUNCTION
__LEAVE_FUNCTION
这两个宏的定义是
#define __ENTER_FUNCTION {try{
#define __LEAVE_FUNCTION }catch(...){AssertSpecial(FALSE,__FUNCTION__);}}
也就是说武侠世界里的大多数函数的开头和结尾都会用到这两个函数,至于在代码在哪里抛出错误呢?
下面是武侠世界World的主循环函数
void ServerManager::Loop( )
{
__ENTER_FUNCTION
while( IsActive() )
{
BOOL ret = FALSE ;
UINT uTime = g_pTimeManager->CurrentTime() ;
_MY_TRY
{
ret = Select( ) ;
Assert( ret ) ;
ret = ProcessExceptions( ) ;
Assert( ret ) ;
ret = ProcessInputs( ) ;
Assert( ret ) ;
ret = ProcessOutputs( ) ;
Assert( ret ) ;
}
_MY_CATCH
{
}
_MY_TRY
{
ret = ProcessCommands( ) ;
Assert( ret ) ;
}
_MY_CATCH
{
}
_MY_TRY
{
ret = HeartBeat( ) ;
Assert( ret ) ;
}
_MY_CATCH
{
}
_MY_TRY
{
ret = g_pOnlineUser->HeartBeat( uTime ) ;
Assert( ret ) ;
}
_MY_CATCH
{
}
_MY_TRY
{
ret = g_pCountryManager->HeartBeat( uTime ) ;
Assert( ret ) ;
}
_MY_CATCH
{
}
_MY_TRY
{
ret = g_pTeamList->HeartBeat( uTime ) ;
Assert( ret ) ;
}
_MY_CATCH
{
}
_MY_TRY
{
ret = g_pChatCenter->HeartBeat( uTime ) ;
Assert( ret ) ;
}
_MY_CATCH
{
}
_MY_TRY
{
ret = g_pGuildManager->HeartBeat( uTime ) ;
Assert( ret ) ;
}
_MY_CATCH
{
}
_MY_TRY
{
ret = g_pCityManager->HeartBeat( uTime ) ;
Assert( ret ) ;
}
_MY_CATCH
{
}
_MY_TRY
{
ret = g_pMailCenter->HeartBeat( uTime ) ;
Assert( ret ) ;
}
_MY_CATCH
{
}
_MY_TRY
{
ret = g_pSceneInfo->HeartBeat( uTime ) ;
Assert( ret ) ;
}
_MY_CATCH
{
}
_MY_TRY
{
ret = g_pWorldTimeInfo->HeartBeat( uTime ) ;
Assert( ret ) ;
}
_MY_CATCH
{
}
};
__LEAVE_FUNCTION
}
其实这写得相当明了,Select( ) 就是接收网络信息,HeartBeat( )就是心跳等等。
里面的Assert是自己定义的一个宏
#define Assert(expr) ((VOID)((expr)?0:(__assert__(__FILE__,__LINE__,__FUNCTION__,#expr),0)))
#define AssertEx(expr,msg) ((VOID)((expr)?0:(__assertex__(__FILE__,__LINE__,__FUNCTION__,#expr,msg),0)))
#define AssertSpecial(expr,msg) ((VOID)((expr)?0:(__assertspecial__(__FILE__,__LINE__,__FUNCTION__,#expr,msg),0)))
VOID __assert__ ( const CHAR * file , UINT line , const CHAR * func , const CHAR * expr )
{
CHAR szTemp[1024] = {0};
#ifdef __LINUX__ //换个格式
sprintf( szTemp, "[%s][%d][%s][%s]\n", file, line, func, expr ) ;
#else
sprintf( szTemp, "[%s][%d][%s][%s]", file, line, func, expr ) ;
#endif
__show__(szTemp) ;
}
VOID __show__( const CHAR* szTemp )
{
#ifdef __LINUX__
printf("Assert:%s",szTemp);
#endif
//保存日志
#ifndef GAME_CLIENT
FILE* f = fopen( "./Log/assert.log", "a" ) ;
if (f != NULL)
{
fwrite( szTemp, 1, strlen(szTemp), f ) ;
fwrite( "\r\n", 1, 2, f ) ;
fclose(f) ;
}
#endif
#if defined(__WINDOWS__)
static MyLock lock ;
if( g_Command_Assert!=1 )
{
lock.Lock() ;
INT iRet = ::MessageBoxA( NULL, szTemp, "异常", MB_OK ) ;
lock.Unlock() ;
}
#elif defined(__LINUX__)
#endif
#ifdef GAME_CLIENT
throw(std::string(szTemp));
#else
throw(1);
#endif
}
最终会在__show__中throw错误,做成了一个统一的错误处理接口。
这是相当于用
Assert( ret ) ;
代替了
if ( !ret )
{
printf("error\n");
return;
}
这样使程序更清晰明了。
至于为什么还要定义
#define _MY_TRY try
#define _MY_CATCH catch(...)
大家可以思考一下
分享到:
相关推荐
前端开源库-async-try-catchAsync Try Catch,Async Try Catch
? Swift do-try-catch的语法糖衣
一个非常简单的try-throw-catch源码
try块中包含可能会产生异常的代码,当try块内的代码发生异常时,程序...另外,finally块是可选的,它会在try-catch块执行完毕后始终被执行,无论是否发生异常。finally块通常用于释放资源、关闭文件等必要的清理工作。
try { Console.Write("请输入整数x:"); int x = Convert.ToInt32(Console.ReadLine()); Console.Write("请输入整数y:"); int y = Convert.ToInt32(Console.ReadLine()); Console.WriteLine("x/y={0}", x / y);...
前端开源库-trycatchTrycatch,一个基于异步域的异常处理程序,具有node.js的长堆栈跟踪
try-catch的用法和含义,欢迎学习
:rocket: 不试 :rocket: 删除那些难看的try-catch-finally块,清理代码库! :smiling_face_with_heart-eyes: 关于在可能期望方法throw的代码库中工作可能会导致逻辑包裹在try-catch块中的情况。 它还导致其他代码...
try-catch-finally捕获异常try-catch-finally捕获异常
使用try-catch-finally处理异常
ASP.NET最佳异常处理:try-catch语句捕获异常 ASP.NET最佳异常处理:try-catch语句捕获异常
摆脱async/await功能的try/catch包装器。 为什么? 不必要的嵌套 失败并不总是错误,但是try/catch意味着处理错误 你应该总是catch 安装 npm i async-nocatch # or yarn add async-nocatch import nocatch from ...
java中try catch的用法 java try catch的用法 java中 try catch的用法
java try…catch嵌套捕获异常的实例 java try…catch嵌套捕获异常的实例
后备语法糖,用于Swift do-try-catch。 乍一看,值=尝试fallback(试试get(“ A”),尝试get(“ B”),尝试get(“ C”),尝试get(“ D”))等效于:do {value = try get (“ A”)} catch {后备语法糖,...
java try…catch捕获异常的实例 java try…catch捕获异常的实例
异常处理try catch在vc中的用法.zip visual c++ try catch处理异常
在C语言中,使用goto和标签的方式模拟try catch的功能,使用setjmp和longjmp方式模拟try catch的功能,两种方式都可以使用,setjmp的方式可以支持try catch嵌套,goto的方式不支持嵌套,但是jmpbuf的开销是比较大的...
使用try-catch写的小程序,希望能够对大家学习C++有所帮助
Java的 try 与 catch finally关键字的使用