2013-08-16 14 views
5

Sto sperimentando con l'estensione dei componenti CCMenuItem di cocos2d-x e ho trovato qualcosa che non ho visto prima in C++. Sarebbe utile se qualcuno approfondire ciò che sta accadendo con le loro dichiarazioni di puntatore a funzioneComprensione del C++ cocos2d-x uso dei puntatori di funzioni

La classe base per la maggior parte degli oggetti cocos2d-X è CCObject che ha la seguente definizione

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) 

Quindi al di fuori della CCObject class, ma all'interno del namespace cocos2d, esiste una dichiarazione per i puntatori di funzione e le macro helper per usarli. Sono corretto nel chiamare queste dichiarazioni per i puntatori di funzione?

Capisco che typedef sta associando una parola chiave con un tipo (Vedi Typedef function pointer?) e che il tipo restituito deve essere vuoto e la funzione deve avere un argomento obbligatorio di CCObject *. Tuttavia, mi manca la comprensione del suo utilizzo, della sua portata e del modo in cui C++ tratta il passaggio di una funzione attraverso un'altra funzione.

Domanda 1

non sto seguendo come interpretare la portata del puntatore a funzione dichiarata. Nella loro dichiarazione, mostrano il puntatore alla funzione che viene esaminato dalla classe CCObject. Come dovrei interpretarlo? Significa che quando viene assegnata quella funzione appartiene come funzione membro a CCObject? Questo mi confonde poiché è definito al di fuori del corpo della classe ma con ambito CCObject.

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

Domanda 2

Nella classe cocos2d-x CCMenuItem, ha un metodo factory statico definito di seguito

// 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; 
}; 

Quindi questo typedef significa che quando passo di una funzione che , Sto passando per valore con un puntatore? Come gestirà C++ se la funzione non è stata passata dal puntatore. Una funzione è trattata come un oggetto con un costruttore di copie?

Apprezzo qualsiasi aiuto e consiglio. Grazie

risposta

6

void (CCObject::*)(CCObject*) è un metodo puntatore tipo (un tipo di puntatore all'elemento), non un puntatore funzione ordinaria. È un puntatore che può puntare a un metodo di istanza della classe CCObject che accetta un parametro del tipo CCObject*. Il tipo di classe è un metodo di fa parte del tipo di puntatore (indicato dallo CCObject::), simile ai parametri (poiché al di sotto, un puntatore all'oggetto corrente è un parametro nascosto a tutti i metodi di istanza, this).

Ildefinisce semplicemente SEL_MenuHandler come sinonimo di quel tipo di puntatore del metodo.

Per utilizzare un puntatore metodo, è necessario fornire sia un'istanza di agire come this, così come gli argomenti, usando una sintassi simile a questo:

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

Come sarebbe C++ gestire questa situazione se il la funzione non è stata passata dal puntatore. Una funzione è trattata come un oggetto con un costruttore di copie?

In C/C++, non è possibile avere un'espressione di "tipo funzione" o "tipo metodo". Ogni volta che si tenta di ottenere qualcosa di "tipo funzione", viene automaticamente convertito in un tipo "puntatore a funzione".

+0

Grazie, questo è stato utile –

Problemi correlati