2013-08-16 9 views
5

Cocos2d-x CCMenuItemコンポーネントを拡張して実験しています。これまでにC++で見たことのないものが出てきました。誰かが自分の関数ポインタの宣言で何が起こっているかについて詳しく説明するかどうCocos2d-x関数ポインタの使用を理解する

最もcocos2d-xのオブジェクトの基本クラスは、CCObjectの外

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) 

だから、次のように定義していCCObjectであることは参考になりますしかし、cocos2dネームスペースには、それらを使用するための関数ポインタとヘルパーマクロの宣言が存在します。これらの宣言を関数ポインタとして呼び出すのは正しいですか?

typedefがキーワードをタイプ(Typedef function pointer?を参照)に関連付けていること、戻り値の型が無効で、関数がCCObject *の1つの必須引数を持っている必要があることを理解しています。しかし、私はその適切な使用法、範囲、そしてC++が別の関数を通して関数を渡す方法を理解することに迷っています。

質問1

私が宣言された関数ポインタの範囲をどのように解釈するか、次のではないのです。彼らの宣言では、関数ポインタがCCObjectクラスによってスコープされていることを示しています。これをどのように解釈すべきですか?これは、その関数がCCObjectのメンバ関数として属していることを意味しますか?これは、クラス本体の外側で定義されていてもCCObjectでスコープされているので、私は混乱しています。

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

質問cocos2d-xのCCMenuItemクラスで2

、それはそう、このtypedefは、私は機能にそれを渡したときにすることを意味してい

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

の下に定義された静的なファクトリメソッドを持っています、私はポインタで値渡しですか?関数がポインタによって渡されなかった場合、C++はこれをどう処理しますか?関数はコピーコンストラクタを持つオブジェクトのように扱われますか?

私は何か助けと助言をいただきありがとうございます。おかげで

答えて

6

void (CCObject::*)(CCObject*)メソッドポインタタイプ(部材からポインタの一種)、ではない通常の関数ポインタです。それは、CCObject*型のパラメータを取るCCObjectクラスのインスタンスメソッドを指すポインタです。メソッドのクラスの型は、パラメータと同様のポインタ型(CCObject::と表示されます)の一部です(下にあるため、「現在のオブジェクト」へのポインタはすべてのインスタンスメソッドの隠しパラメータです。this)。

typedefは、単にそのメソッドポインタ型の同義語となるようにSEL_MenuHandlerを定義します。

メソッドポインタを使用するには、あなたがthisとしての役割を果たすだけでなく、引数が、このような構文を使用して、インスタンスの両方を提供する必要があります場合はC++これを処理する方法を

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

関数がポインタによって渡されませんでした。 関数はコピーコンストラクタを持つオブジェクトのように扱われますか?

C/C++では、「関数型」または「メソッド型」の式を持つことはできません。 「関数型」の何かを取得しようとするたびに、自動的に「関数型へのポインタ」型に変換されます。

+0

ありがとうございました –

関連する問題