首页 技术 正文
技术 2022年11月6日
0 收藏 603 点赞 606 浏览 2621 个字

先看一段代码如何在Android中加入返回按键的响应

<span style="font-size:18px;">自己派生CCKeypadDelegate的子类,然后注册为键盘事件的委托调用class MyKeypadDelegate:public CCKeypadDelegate
{
public:
virtual void keyBackClicked();
virtual void keyMenuClicked();
};m_pKeypadDlegate = new MyKeypadDelegate();
pDirector->getKeypadDispatcher()->addDelegate(m_pKeypadDlegate);</span>

原帖:http://blog.csdn.net/lamp_zy/article/details/8210303

第一眼看到这段代码并没有什么问题,但是在自己在测试的时候却发现一个问题,运行报错。通过错误追踪发现了报错的地方。

在CCKeypadDelegate.cpp中有这么一段:

<span style="font-size:18px;">    bool CCKeypadHandler::initWithDelegate(CCKeypadDelegate *pDelegate)
{
CCAssert(pDelegate != NULL, "It's a wrong delegate!");
m_pDelegate = pDelegate;
dynamic_cast<CCObject*>(pDelegate)->retain(); //这里
return true;
}</span>

其中 dynamic_cast<CCObject *>(pDelegate)->retain();报错,报错的原因是pDelegate的引用计数为0。这就奇怪了,明明外部调用的地方已经赋值了。在考虑一下,想到了曾经看到的一篇文章:

CCTargetedTouchDelegate 的继承 和 dynamic_cast

想写个可以响应touch的sprite

类定义成了这个样子:

[cpp] view
plain
copy

  1. class GemBoard : public CCSprite, CCTargetedTouchDelegate

然后注册touch消息的时候

[cpp] view
plain
copy

  1. CCTouchDispatcher::sharedDispatcher()->addTargetedDelegate(this, 0, true);

在这挂了,查了一下午,挂在了

-addTargetedDelegate

-CCTargetedTouchHandler::handlerWithDelegate

-initWithDelegate

-CCTouchHandler::initWithDelegate

-dynamic_cast<CCObject*>(pDelegate)->retain();

-void CCObject::retain(void)

跟到这里,编译器告诉我CCObject的this指针是0,我晕呀。感觉太诡异了。

原因:CCTargetedTouchDelegate在上面的写法中是私有继承,而根据dynamic_cast的作用:(运算符可以在执行期决定真正的类型。如果downcast是安全的(也就说,如果基类指针或者引用确实指向一个派生类对象)这个运算符会传回适当转型过的指针。如果downcast不安全,这个运算符会传回空指针(也就是说,基类指针或者引用没有指向一个派生类对象)。)上面的情况就合情合理了。

今天学到了2个知识点:

1. class B: public A, C  这种情况下A是public继承,C是private继承;class B: A 这个A也是private继承

2.dynamic_cast 除了public 的其他都返回null

所以改成

[cpp] view
plain
copy

  1. class GemBoard : public CCSprite, public CCTargetedTouchDelegate

原文地址:http://blog.csdn.net/bill_ming/article/details/9352449

突然明白了,原来如此。赶紧看看CCKeypadDelegate.h文件的继承关系,源码如下:

<span style="font-size:18px;">    class CC_DLL CCKeypadDelegate //没继承
CCObject
{
public:
// The back key clicked
virtual void keyBackClicked() {}
// The menu key clicked. only available on wophone & android
virtual void keyMenuClicked() {};
};</span>

问题就出在这里,引擎尝试将CCKeypadDelegate 类型的指针转换成CCObject类型,但是CCKeypadDelegate 并没有继承
CCObject,所以dynamic_cast 运算后返回的是0,造成了程序中断退出

问题找到了那么就好解决了,一种网上比较流行的解决方式,修改cocos2d-x的源码,将这句话屏蔽掉。呵呵,虽然这是比较快捷的修改方式,但是为以后引擎升级和后续修改埋下了深深的隐患。所以这一种方式个人极不推荐。因此我们就要寻找新的解决方式。既然引擎是要将CCKepadDelegate强制转换为CCObject类型,而这个delegate又是我们自己定义的所以,我们只要将这个自定义的delegate继承CCObject就可以了,代码如下:

class MyKeypadDelegate:public CCKeypadDelegate,<span style="color:#FF0000;">public CCObject</span>
{
public:
virtual void keyBackClicked();
virtual void keyMenuClicked();
};m_pKeypadDlegate = new MyKeypadDelegate();
pDirector->getKeypadDispatcher()->addDelegate(m_pKeypadDlegate);

再次运行程序,一切OK了

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,083
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,558
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,407
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,180
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,816
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,899