视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
Cocos2d-x中的强制类型转换
2020-11-09 08:32:37 责编:小采
文档


为了完成强制类型转换,C中已经为我们提供了4中标准方法,它们是dynamic_cats, static_cast, const_cast, reinterpret_cast,用法形式如:dynamic_cast类型说明符(表达式),之所以分成4类,就表示他们各自有着不同的使用环境。 我觉的 通常情况下用dynamic_c

为了完成强制类型转换,C++中已经为我们提供了4中标准方法,它们是dynamic_cats, static_cast, const_cast, reinterpret_cast,用法形式如:dynamic_cast<类型说明符>(表达式),之所以分成4类,就表示他们各自有着不同的使用环境。


我觉的通常情况下用dynamic_cast最好,它检查的更严格些,其次是static_cast,而后两者也就是const_cast和reinterpret_cast较之前两者貌似不太常用(我会告诉你我根本就没用过吗...),而且也不推荐使用,const_cast在用于去除const的地方还是有所发挥的,reinterpret_cast在转换时,不会在内存中进行补足比特位(例如int转换到double,需要补足4字节),这往往是不安全的,而且代码也是不可移植的。
所以我主要介绍的还是static_cast和dynamic_cast。


1、static_cast
static_cast类似C风格的强制类型转换。它适用于基类和子类之间转换:其中子类指针转换成父类指针是安全的;但父类指针转换成子类指针是不安全的。用法如下:

[cpp] view plaincopy

  1. class A { ... };
  2. class B { ... };
  3. class D : public B { ... };
  4. void f(B* pb, D* pd)
  5. {
  6. D* pd2 = static_cast(pb); // 不安全, pb可能只是B的指针
  7. B* pb2 = static_cast(pd); // 安全的
  8. A* pa2 = static_cast(pb); //错误A与B没有继承关系
  9. }

在cocos2dx 中,有这样的一种用法:

[cpp] view plaincopy

  1. auto boy = Sprite::create("boy.png");//创建一个精灵
  2. boy->setPosition(Point(200,400));
  3. boy->setTag(99);//设置精灵的tag
  4. this->addChild(boy,2);
  5. //在其他函数里,我们要使用到精灵boy,用下面的方法调用
  6. auto boy = static_cast(this->getChildByTag(99));
  7. boy->setPosition(Point(50,50));//运行后精灵boy的坐标发生改变,说明获取成功

上面的情况是我在知道tag为99的child是一个Sprite类,所以我才会将其取出来后强制转化为Sprite*,可是如果我只知道有个tag为99的东东,但不知道到底是什么类型的,那会怎么做呢?步骤其实很简单:
1、取出一个骰子;
2、使出吃奶的力气摇骰子;
3、根据点数的大小决定该转换成什么类型...................
这里假设要转换成LabelTTF类型的(很明显猜错了,应该是Sprite型的)

[cpp] view plaincopy

  1. auto label = static_cast(this->getChildByTag(99));
  2. label->setString("天才一般的我肯定猜对了,哇哈哈,动感超人!");//呵呵,呵呵

上面这种做法会产生什么后果呢?呵呵。
其实我只是想通过这种方法告诉小伙伴们,珍爱生命,远离。
那么,有什么办法可以避免上述这种不靠谱的强制类型转换吗?回答当然是有的,那就是比安全那啥还安全的dynamic_cast

2、dynamic_cast
与其他强制类型转换不同,dynamic_cast在转换过程中涉及类型检查。如果绑定到引用或指针的对象不是目标类型的对象,则dynamic_cast失败,并返回nullptr。
换句话说:如果你要将Sprite* 强制转化为LabelTTF,dynamic_cast绝对不允许你这么乱搞的!它会用返回nullptr的形式告诉你,LabelTTF和Sprite并不是同一物种,重口味者慎入!
下面修改之前的代码:

[cpp] view plaincopy

  1. auto label = dynamic_cast(this->getChildByTag(99));
  2. if( label )
  3. {
  4. label->setString("有了dynamic_cast,老板再也不用担心我乱来了");
  5. }
  6. else
  7. {
  8. CCLOG("Attention : label doesn't point to LabelTTF Objective");
  9. }


恩,我的理解就只是这样啦,再说下去又要暴露些什么了...

下载本文
显示全文
专题