do{}while(0)与CC_BREAK_IF的绝妙搭配

do{}while(0)与CC_BREAK_IF的绝妙搭配,第1张

概述从一开始觉得没有必要,到觉得非常好用,我经历了大概两个月的时间,下面来总结一下什么情况下使用这种结构吧。 第一种情况:当加载文件的时候,如果加载文件失败,需要报错的时候。 当前,可以用try{}catch(){}finally{}这种结构,但是这样做会极大的增加编译后文件的大小,使用do{}while(0)加上CC_BREAK_IF就能实现一样的效果,而且不增加文件的大小。 下面是一个例子: ?

从一开始觉得没有必要,到觉得非常好用,我经历了大概两个月的时间,下面来总结一下什么情况下使用这种结构吧。

第一种情况:当加载文件的时候,如果加载文件失败,需要报错的时候。

当前,可以用try{}catch(){}finally{}这种结构,但是这样做会极大的增加编译后文件的大小,使用do{}while(0)加上CC_BREAK_IF就能实现一样的效果,而且不增加文件的大小。

下面是一个例子:

?
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 bool GameScene::setScene() { do { auto node = SceneReader::getInstance()->createNodeWithScenefile( "publish/GameScene.csb" ); CC_BREAK_IF(!node); m_UI_Background->addChild(node); auto Checkerboard = (Comrender*)(node->getChildByTag( 10009 )->getComponent( "GUIComponent" )); CheckerboardUI = Checkerboard->getNode(); //设置按钮 m_btn_Setting = dynamic_cast<button*>(CheckerboardUI->getChildByname( "button_Setting" )); CC_BREAK_IF(!m_btn_Setting); //音乐按钮 m_btn_Music = dynamic_cast<button*>(CheckerboardUI->getChildByname( "button_Music" )); CC_BREAK_IF(!m_btn_Music); //棋盘锁 m_btn_Lock = dynamic_cast<button*>(CheckerboardUI->getChildByname( "button_Lock" )); CC_BREAK_IF(!m_btn_Lock); //棋盘图片 m_Image_Checkerboard = dynamic_cast<imagevIEw*>(CheckerboardUI->getChildByname( "Image_Checkerboard" )); CC_BREAK_IF(!m_Image_Checkerboard); m_Checkerboard = Checkerboard::create(m_Image_Checkerboard); auto SelectPeople = (Comrender*)(node->getChildByTag( 10031 )); SelectPeopleUI = SelectPeople->getNode(); this ->setCampBtn(); return true ; } while ( 0 ); cclOG( "ERROR:Load Resources Fail in GameScene::setScene" ); false ; }</imagevIEw*></button*></button*></button*>

如果在中途出现任何一个变量执行后还是nullptr,那么就CC_BREAK_IF,然后显示错误日志,最后返回false给上层函数进行处理。这样的处理方式是不是既优雅又方便快速,又避免了可能错误使用空指针。


第二种情况:当无论如何都需要在函数最后进行清理 *** 作的时候。

下面举一个比较典型的例子,就是在函数开头声明了一个new的指针(非智能指针),按照正常的流程,需要delete,但是我们无法保证程序会不会在中途就return了,因为后续的维护者并不知道还有这个清除 *** 作需要执行,下面是一个对比例子:

?

26
//error voID test() GameScene* gamescene = new GameScene; // doSomething... if (gamescene->getChildByTag( 111 ) == nullptr) { return ; } // doSomething... delete gamescene; gamescene = nullptr; } //right test1() { GameScene; { // doSomething... CC_BREAK_IF(gamescene->getChildByTag( ) == nullptr); // doSomething... ); delete gamescene; gamescene = nullptr; }

使用CC_BREAK_IF可以保证永远都会执行到最后两行,也就不会出现内存泄露。

但是这个组合也不是万能的,下面就说一个不适合这种结构的情况吧。当do{}while(0)的括号中存在循环的时候,就不适用这个组合了,因为break毕竟只能跳出一层循环,下面是一个例子:

12 test2() for ( int i = ;i < 5 ;++i) { // doSomething... CC_BREAK_IF(i> 4 ); // doSomething... "永远显示这一行日志" ); ); 我们希望的是,CC_BREAK_IF能跳出do{}while(0)循环,但是实际上,只跳出了for循环,所以使用do{}while(0)和CC_BREAK_IF的时候,需要确保其内部不能存在其他循环,如果存在循环,还是建议使用try{}catch(){} 总结

以上是内存溢出为你收集整理的do{}while(0)与CC_BREAK_IF的绝妙搭配全部内容,希望文章能够帮你解决do{}while(0)与CC_BREAK_IF的绝妙搭配所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1062310.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)