从一開始认为没有必要,到认为很好用。我经历了大概两个月的时间,以下来总结一下什么情况下使用这样的结构吧。

第一种情况:当载入文件的时候,假设载入文件失败,须要报错的时候。

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

以下是一个样例:

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();
//设置button
m_btn_Setting = dynamic_cast<Button*>(CheckerboardUI->getChildByName("Button_Setting"));
CC_BREAK_IF(!m_btn_Setting);
//音乐button
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)->getComponent("GUIComponent"));
SelectPeopleUI = SelectPeople->getNode();
this->setCampBtn(); return true;
}while(0);
CCLOG("ERROR:Load Resources Fail in GameScene::setScene");
return false;
}

假设在中途出现不论什么一个变量运行后还是nullptr。那么就CC_BREAK_IF,然后显示错误日志。最后返回false给上层函数进行处理。这种处理方式是不是既优雅又方便高速,又避免了可能错误使用空指针。

另外一种情况:当不管怎样都须要在函数最后进行清理操作的时候。

以下举一个比較典型的样例,就是在函数开头声明了一个new的指针(非智能指针),依照正常的流程,须要delete。可是我们无法保证程序会不会在中途就return了,由于兴许的维护者并不知道还有这个清除操作须要运行。以下是一个对照样例:

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

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

可是这个组合也不是万能的,以下就说一个不适合这样的结构的情况吧。

当do{}while(0)的括号里存在循环的时候,就不适用这个组合了。由于break毕竟仅仅能跳出一层循环,以下是一个样例:

void test2()
{
do{
for(int i = 0;i <5;++i)
{
// doSomething...
CC_BREAK_IF(i>4);
// doSomething...
}
CCLOG("永远显示这一行日志");
}while(0);
}

我们希望的是,CC_BREAK_IF能跳出do{}while(0)循环。可是实际上。仅仅跳出了for循环,所以使用do{}while(0)和CC_BREAK_IF的时候,须要确保其内部不能存在其它循环,假设存在循环,还是建议使用try{}catch(){}

do{}while(0)与CC_BREAK_IF的绝妙搭配的更多相关文章

  1. cocos2dx中替代goto的用法:do{}while(0)和CC_BREAK_IF

    我们时常会调用某个函数来创建一个对象,但由于内存不足或其他异常情况发生时对象可能会创建失败,创建失败我们就要结束当前程序转到错误处理地方去处理错误或释放已生成的对象. int* p1 = new in ...

  2. spark1.2.0编译

    spark 有三种编译方式:SBT.MAVEN.make-distribution.sh.SBT.MAVEN两种方式打出来的包比较大,不适合部署使用.因此我们通常使用第三种方式打包. ./make-d ...

  3. BaiduSpeechDemo【百度语音SDK集成】(基于v3.0.7.3)

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 本Demo将百度语音SDK(其中一部分功能)和自定义的UI对话框封装到一个module中,便于后续的SDK版本更新以及调用. 本De ...

  4. C语言工具:LCC-Win32+v3.0

    LCC-Win32+v3.0(带汉化).rar  小巧精悍的工具 安装步骤: 1.先安装 LCC-Win32V3.0.exe 假如安装目录为:C:\lcc 2.再安装 LCC-Win32V3.0汉化补 ...

  5. hadoop-2.6.0.tar.gz + hive-1.0.0.tar.gz + pig-0.15.0.tar.gz的安装

    这里,为什么选择用hadoop-2.6.0.tar.gz  +   hive-1.0.0.tar.gz是为了搭配兼容. hadoop-2.6.0.tar.gz  +   hive-1.0.0.tar. ...

  6. 原生js+css3实现图片自动切换,图片轮播

    运用CSS3transition及opacity属性 制作图片轮播动画 自己这两天根据用js来控制触发CSS3中transition属性,从而写出来的以CSS3动画为基础,js控制过程的图片轮播 运用 ...

  7. SQL 基本(Head First)

    CREATE TABLE my_contacts( last_name VARCHAR(30), first_name VARCHAR(30), email VARCHAR(50), gender C ...

  8. Spring 整合Redis 出现 afterPropertiesSet signature: ()V) Incompatible argument to function 解决办法

    正在做SpringMVC+Redis整合的练习 使用的是 spring-data-redis 和 Jedis 配置好之后出现了以下错误: Caused by: java.lang.VerifyErro ...

  9. cocod2d-x 之 HelloWorld

    cocos2d-x 2.2创建项目 进入cocos2d-x-2.2/tools/project-creator,运行命令 python create_project.py -project MyGam ...

随机推荐

  1. WC 2018/CTSC 2018/APIO 2018 游记

    (要写CTSC的时候才想起来没写WC2018,那就粗略回顾一下吧hhhhh) WC 2018(简略版): 大概和 一个宁夏和一个天津的大哥一个宿舍hhhh,字典序分宿舍真是奇妙. WC讲课真的不是人听 ...

  2. bean装配--注解

    1,Dao层 package com.songyan.zhujie; public interface UserDao { public void say(); } package com.songy ...

  3. md5是哈希算法的改进加强,因为不同原始值可能hash结果一样,但md5则改善了用于验证消息完整性,不同md5值原始值也必将不一样

    md5是哈希算法的改进加强,因为不同原始值可能hash结果一样,但md5则改善了用于验证消息完整性,不同md5值原始值也必将不一样

  4. UVa 407

    此问题与求上升序列最大和类似,可以作为DAG模型计算.将每一快砖分解为3块,将所有砖块按照底排序,注意sort排序中涉及到底的两个参数x,y,这时候一定要有优先排,比如先排x再排y,不能同时排x和y, ...

  5. Swift入门(一)——基本的语法

    近期開始学习swift.把学习的过程和总结整理成一个系列.方便日后回想总结. 基本的语法 基础语法 swift中每一行结束后不须要加分号.多个语句在同一行内须要用分好隔开 //表示凝视.或者用/* - ...

  6. WIN7无法卸载掉中文繁体注音输入法

    WIN7无法卸载掉中文繁体注音输入法 不知何时系统里被自动安装了个中文繁体的注音输入法,每次启动都会替换默认的简体搜狗拼音,而且最要命的是在输入法选择栏里面没有出现这个繁体的输入法,而任务栏里却总是有 ...

  7. mysql行转列,单列转多行

    行转列 使用CASE语句: SELECT SUM(CASE USER_NAME='A' THEN KILLS END) AS 'A', SUM(CASE USERNAME='B' THEN KILL ...

  8. C++ 获取URL图片、html文件,CInternetSession 【转】

    http://blog.csdn.net/gnixuyil/article/details/7688439 获取网络图片 CString URL="http://www.google.com ...

  9. 在scala中:: , +:, :+, :::, +++的区别总结

    初学Scala的人都会被Seq的各种操作符所confuse.下面简单列举一下各个Seq操作符的区别. 4种操作符的区别和联系 :: 该方法被称为cons,意为构造,向队列的头部追加数据,创造新的列表. ...

  10. Jenkins 无法下载插件的解决办法

    有时候在安装插件时可能会出现下图的问题: 这应该是由于天朝的墙导致的,所以笔者就用了手动安装的方式 到https://wiki.jenkins-ci.org/display/JENKINS/Plugi ...