首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

cocos2d-x 类回调 及类的成员函数的函数指针赋值有关问题

2013-11-06 
cocos2d-x 类回调 及类的成员函数的函数指针赋值问题本帖最后由 ljf551 于 2013-11-01 18:33:59 编辑CCObj

cocos2d-x 类回调 及类的成员函数的函数指针赋值问题
本帖最后由 ljf551 于 2013-11-01 18:33:59 编辑 CCObject 是以下所有类的基类.(CCObjectParent, CCObjectRun)
cocos2d-x中定义了此种类型:
typedef void (CCObject::*SEL_CallFuncO)(CCObject*);  
又定义了一个宏:
#define schedule_selector(_SELECTOR)  (SEL_CallFuncO)(&_SELECTOR)
在以下代码中:


// CCObjectParent 成员函数
void CCObjectParent::run()
{
    ?CCObjectRun* pRun = new CCObjectRun();  
    ?CCObjectParent* pObjectB = new CCObjectParent();
    ?pRun->run(this, schedule_selector(CCObjectParent::runCallBack)); // 语句一

    // OR 

    ?pRun->run(pObjectB , schedule_selector(CCObjectParent::runCallBack)); // 语句二 ?
}
void CCObjectParent::runCallBack(CCObject* )
{
}
/************************/
// CCObjectRun 成员函数

void CCObjectRun ::run(CCObject* pSelectorTarget, SEL_CallFuncO selector)
{
  // .................
  // 调用返回

    if(pSelectorTarget && selector)
    {
       (pSelectorTarget ->*selector)(this); // 语句三
    }
}



问题一:
   在C中:一般函数的函数名就是(定义的类型)指针,只不过是常量,再定义一个函数指针就是一个变量,这个变量可以指向这一类函数的地址。
   语句一中的第二个实参: 是类CCObjectParent 所有的对象的成员函数(函数名)CCObjectParent::runCallBack()的地址 还是只是类CCObjectParent某一成员的地址(这儿是this)?
(好别扭 )第一种对实参的认为应该解释为:每个类的某一成员函数对所有对象共用一个地址;
     第二种为:每个类的某一成员函数对于此类的所有对象都有自己的地址; 我是认为第二种解释合理些(对元表没深入)。
   如果是第二种解释,那么语句二第二参数 写法就不合理, 是否写为 :
  ?pRun->run(pObjectB ,(SEL_CallFuncO)(&(pObjectB->CCObjectParent::runCallBack));(这样(pObjectB->CCObjectParent::runCallBack)好象又不合理)。

求大神指教。 类成员函数的函数地针是什么?

二,对 CCObjectParent::runCallBack 取地址:即(&(CCObjectParent::runCallBack))此类型 是怎么强转为 SEL_CallFuncO类型的 ?
           
[解决办法]
引用:
CCObject 是以下所有类的基类.(CCObjectParent, CCObjectRun)
cocos2d-x中定义了此种类型:
typedef void (CCObject::*SEL_CallFuncO)(CCObject*);  
又定义了一个宏:
#define schedule_selector(_SELECTOR)  (SEL_CallFuncO)(&_SELECTOR)
在以下代码中:

// CCObjectParent 成员函数
void CCObjectParent::run()
{
    ?CCObjectRun* pRun = new CCObjectRun();  
    ?CCObjectParent* pObjectB = new CCObjectParent();
    ?pRun->run(this, schedule_selector(CCObjectParent::runCallBack)); // 语句一

    // OR 

    ?pRun->run(pObjectB , schedule_selector(CCObjectParent::runCallBack)); // 语句二 ?
}
void CCObjectParent::runCallBack(CCObject* )
{
}
/************************/
// CCObjectRun 成员函数

void CCObjectRun ::run(CCObject* pSelectorTarget, SEL_CallFuncO selector)
{
  // .................
  // 调用返回

    if(pSelectorTarget && selector)
    {
       (pSelectorTarget ->*selector)(this); // 语句三
    }
}



问题一:
   在C中:一般函数的函数名就是(定义的类型)指针,只不过是常量,再定义一个函数指针就是一个变量,这个变量可以指向这一类函数的地址。
   语句一中的第二个实参: 是类CCObjectParent 所有的对象的成员函数(函数名)CCObjectParent::runCallBack()的地址 还是只是类CCObjectParent某一成员的地址(这儿是this)?
(好别扭 )第一种对实参的认为应该解释为:每个类的某一成员函数对所有对象共用一个地址;
     第二种为:每个类的某一成员函数对于此类的所有对象都有自己的地址; 我是认为第二种解释合理些(对元表没深入)。
   如果是第二种解释,那么语句二第二参数 写法就不合理, 是否写为 :
  ?pRun->run(pObjectB ,(SEL_CallFuncO)(&(pObjectB->CCObjectParent::runCallBack));(这样(pObjectB->CCObjectParent::runCallBack)好象又不合理)。

求大神指教。 类成员函数的函数地针是什么?

二,对 CCObjectParent::runCallBack 取地址:即(&(CCObjectParent::runCallBack))此类型 是怎么强转为 SEL_CallFuncO类型的 ?
           


先ym一下lz吧,cocos2d-x没用过,这里只能说一下我自己的理解:
(1)typedef void (CCObject::*SEL_CallFuncO)(CCObject*); 
这一句将SEL_CallFuncO指定为,一个以CCObject*为参数的、返回void的函数类型,而且,还必须是CCObject内含有的函数,要满足此种条件,则语句一中CCObjectParent::runCallBack必须是CCObject中已经定义的函数(此函数可为virtual的,以实现多态),所以可以实现强制转换。例如:

#include <cstdio>

using namespace std;
class A{
public:
       virtual void print(A* p){ puts("A"); }


};
typedef void (A::*pFun)(A* p);

class B: public A
{
public:
       virtual void print(A* p){ puts("B"); }
};

int main()
{
    pFun f = &A::print;
    B b;
    (b.*f)(&b);
    
    getchar();
    return 0;
}


这里运行之后,即输出B,虽然f是取的&A::print,但却准确调用了子类的print(A* p)
(2)关于成员函数,实际是类级别的东西,而不是对象级别的东西,这里有vtable的一些东西,建议lz自己去查一查



[解决办法]
cocos2d-x的 这种做法是错误的,有隐患。
[解决办法]
引用:
CCObject 是以下所有类的基类.(CCObjectParent, CCObjectRun)
cocos2d-x中定义了此种类型:
typedef void (CCObject::*SEL_CallFuncO)(CCObject*);  
又定义了一个宏:
#define schedule_selector(_SELECTOR)  (SEL_CallFuncO)(&_SELECTOR)
在以下代码中:

// CCObjectParent 成员函数
void CCObjectParent::run()
{
    ?CCObjectRun* pRun = new CCObjectRun();  
    ?CCObjectParent* pObjectB = new CCObjectParent();
    ?pRun->run(this, schedule_selector(CCObjectParent::runCallBack)); // 语句一

    // OR 

    ?pRun->run(pObjectB , schedule_selector(CCObjectParent::runCallBack)); // 语句二 ?
}
void CCObjectParent::runCallBack(CCObject* )
{
}
/************************/
// CCObjectRun 成员函数

void CCObjectRun ::run(CCObject* pSelectorTarget, SEL_CallFuncO selector)
{
  // .................
  // 调用返回

    if(pSelectorTarget && selector)
    {
       (pSelectorTarget ->*selector)(this); // 语句三
    }
}



问题一:
   在C中:一般函数的函数名就是(定义的类型)指针,只不过是常量,再定义一个函数指针就是一个变量,这个变量可以指向这一类函数的地址。
   语句一中的第二个实参: 是类CCObjectParent 所有的对象的成员函数(函数名)CCObjectParent::runCallBack()的地址 还是只是类CCObjectParent某一成员的地址(这儿是this)?
(好别扭 )第一种对实参的认为应该解释为:每个类的某一成员函数对所有对象共用一个地址;
     第二种为:每个类的某一成员函数对于此类的所有对象都有自己的地址; 我是认为第二种解释合理些(对元表没深入)。
   如果是第二种解释,那么语句二第二参数 写法就不合理, 是否写为 :
  ?pRun->run(pObjectB ,(SEL_CallFuncO)(&(pObjectB->CCObjectParent::runCallBack));(这样(pObjectB->CCObjectParent::runCallBack)好象又不合理)。

求大神指教。 类成员函数的函数地针是什么?

二,对 CCObjectParent::runCallBack 取地址:即(&(CCObjectParent::runCallBack))此类型 是怎么强转为 SEL_CallFuncO类型的 ?
           


对你的第一个问题,实际上,就是成员函数的地址。你看看编译后的obj,看他们的符号导出,C++的成员函数是不是都变成了 类名+函数名?实际上你可以想象成,C++的成员函数是用C来模拟的,也即是 类名+函数名(this,vars...)这样。另外,对于你这个猜测“每个类的某一成员函数对于此类的所有对象都有自己的地址”,我想起一个笑话:有个程序员指着一个有上百个方法,但只有一个成员变量的类说,这个东西实例化后后会占很多内存,因为他的代码很多!

第二个问题,就是类似于void*再强转成你要的类型啦。这种方法确实很坑爹,假设你绑定的函数参数跟他期望的类型不一致,那么调用的时候,在退栈的时候会栈溢出,而出错提示会让你莫名其妙。

热点排行