2013-08-16 14 views
5

Eksperymentuję z rozszerzeniem komponentów cocos2d-x CCMenuItem i natknąłem się na coś, czego nie widziałem wcześniej w C++. Dobrze byłoby, gdyby ktoś rozwinąć to, co dzieje się z ich deklaracji wskaźnik funkcjiC++ zrozumienie użycia wskaźników funkcji przy pomocy cocos2d-x

Klasa bazowa dla większości cocos2d-X obiektów jest CCObject który posiada następującą definicję

class CC_DLL CCObject : public CCCopying 
{ 
public: 
    // Code omitted 
}; 

// The part in which I have a question about 
typedef void (CCObject::*SEL_SCHEDULE)(float); 
typedef void (CCObject::*SEL_CallFunc)(); 
typedef void (CCObject::*SEL_CallFuncN)(CCNode*); 
typedef void (CCObject::*SEL_CallFuncND)(CCNode*, void*); 
typedef void (CCObject::*SEL_CallFuncO)(CCObject*); 
typedef void (CCObject::*SEL_MenuHandler)(CCObject*); 
typedef void (CCObject::*SEL_EventHandler)(CCEvent*); 
typedef int (CCObject::*SEL_Compare)(CCObject*); 

#define schedule_selector(_SELECTOR) (SEL_SCHEDULE)(&_SELECTOR) 
#define callfunc_selector(_SELECTOR) (SEL_CallFunc)(&_SELECTOR) 
#define callfuncN_selector(_SELECTOR) (SEL_CallFuncN)(&_SELECTOR) 
#define callfuncND_selector(_SELECTOR) (SEL_CallFuncND)(&_SELECTOR) 
#define callfuncO_selector(_SELECTOR) (SEL_CallFuncO)(&_SELECTOR) 
#define menu_selector(_SELECTOR) (SEL_MenuHandler)(&_SELECTOR) 
#define event_selector(_SELECTOR) (SEL_EventHandler)(&_SELECTOR) 
#define compare_selector(_SELECTOR) (SEL_Compare)(&_SELECTOR) 

Więc poza CCObject class, ale w przestrzeni nazw cocos2d istnieje deklaracja dla wskaźników funkcyjnych i makr pomocniczych do ich użycia. Czy poprawne jest wywoływanie tych deklaracji dla wskaźników funkcji?

Rozumiem, że typedef kojarzy słowo kluczowe z typem (patrz Typedef function pointer?) i że typ zwracany musi być nieważny, a funkcja musi mieć jeden obowiązkowy argument CCObject *. Jednak jestem zagubiony w zrozumieniu jego właściwego użycia, zakresu i sposobu, w jaki C++ traktuje przekazanie funkcji przez inną funkcję.

Pytanie 1

Nie mam następujący sposób interpretować zakres deklarowanej wskaźnika funkcji. W ich deklaracji pokazują wskaźnik funkcji mieszczący się w klasie CCObject. Jak mam to interpretować? Czy oznacza to, że przypisana funkcja należy do funkcji członkowskiej do CCObject? Jest to mylące dla mnie, ponieważ jest zdefiniowane poza ciałem klasy, ale ma zasięg CCObject.

typedef void (CCObject::*SEL_MenuHandler)(CCObject*); 

Pytanie 2

W klasie cocos2d-x CCMenuItem, to statyczna metoda fabrycznie zdefiniowane poniżej

// How does C++ treat the this? Is a function treated like an object here? 
static CCMenuItem* create(CCObject *rec, SEL_MenuHandler selector); 



    CCMenuItem* CCMenuItem::create(CCObject *rec, SEL_MenuHandler selector) 
{ 
    CCMenuItem *pRet = new CCMenuItem(); 
    pRet->initWithTarget(rec, selector); 
    pRet->autorelease(); 
    return pRet; 
} 

bool CCMenuItem::initWithTarget(CCObject *rec, SEL_MenuHandler selector) 
{ 
    setAnchorPoint(ccp(0.5f, 0.5f)); 
    m_pListener = rec; 
    m_pfnSelector = selector; 
    m_bEnabled = true; 
    m_bSelected = false; 
    return true; 
} 

// A snippet from CCMenuItem header 
protected: 
    CCObject*  m_pListener; 
    SEL_MenuHandler m_pfnSelector; // member variable which stores a pointer to a function? 
    int    m_nScriptTapHandler; 
}; 

Więc czy to typedef oznaczać, że kiedy przekazać funkcję it Przechodzę przez wartość wskaźnikiem? Jak obsługiwałby to C++, gdyby funkcja nie została przekazana przez wskaźnik. Czy funkcja traktowana jest jak obiekt z konstruktorem kopiującym?

Doceniam każdą pomoc i porady. Dzięki

Odpowiedz

6

void (CCObject::*)(CCObject*) jest metoda wskaźnik typ (jeden rodzaj wskaźnik do członka), a nie zwykły wskaźnik funkcji. Jest to wskaźnik, który może wskazywać na metodę instancji klasy CCObject, która przyjmuje parametr o typie CCObject*. Typ klasy jest metodą jest częścią typu wskaźnika (oznaczoną przez CCObject::), podobnie jak parametry (ponieważ pod spodem, wskaźnik do "bieżącego obiektu" jest ukrytym parametrem dla wszystkich metod instancji, this).

Parametr typedef definiuje po prostu SEL_MenuHandler jako synonim dla tego typu wskaźnika metody.

użyć wskaźnika metody, trzeba zapewnić zarówno wystąpienie działać jako this, jak również argumenty, za pomocą składni takiego:

CCObject* object; 
CCObject* anotherObject; 
SEL_MenuHandler methodPointer; 
(object->*methodPointer)(anotherObject); 
// or equivalently: ((*object).*methodPointer)(anotherObject); 

Jak C++ z tym poradzić, jeśli funkcja nie została przekazana przez wskaźnik. Czy funkcja jest traktowana jak obiekt z konstruktorem kopiującym?

W języku C/C++ wyrażenie "typ funkcji" lub "typ metody" nie jest możliwe. Za każdym razem, gdy próbujesz uzyskać coś "typu funkcji", jest on automatycznie konwertowany na typ "wskaźnik do funkcji".

+0

Dzięki, to było pomocne –