2013-08-16 50 views
5

Tôi đang thử nghiệm xung quanh với việc mở rộng các thành phần cocos2d-x CCMenuItem và đi qua một cái gì đó mà tôi chưa từng thấy trong C++. Nó sẽ rất hữu ích nếu ai đó sẽ xây dựng trên những gì đang xảy ra với tờ khai con trỏ hàm của họC++ hiểu cocos2d-x sử dụng các con trỏ hàm

Các lớp cơ sở cho hầu hết các đối tượng cocos2d-x là CCObject trong đó có các định nghĩa sau đây

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) 

Vì vậy, bên ngoài của CCObject lớp, nhưng trong không gian tên cocos2d, có tồn tại một khai báo cho các con trỏ hàm và các macro trợ giúp để sử dụng chúng. Tôi có đúng trong việc gọi các khai báo này cho các con trỏ hàm không?

Tôi hiểu rằng typedef đang kết hợp từ khóa với một loại (Xem Typedef function pointer?) và loại trả về phải bị vô hiệu và hàm phải có một đối số bắt buộc của CCObject *. Tuy nhiên tôi bị mất trong sự hiểu biết cách sử dụng thích hợp, phạm vi của nó, và cách xử lý C++ truyền một hàm thông qua một hàm khác.

Câu hỏi 1

Tôi không tuân theo cách giải thích phạm vi của con trỏ chức năng công bố. Trong khai báo của họ, chúng hiển thị con trỏ hàm bị scoped bởi lớp CCObject. Tôi nên giải thích điều này như thế nào? Điều này có nghĩa là khi nó được gán chức năng đó thuộc về một hàm thành viên cho CCObject không? Điều này là khó hiểu với tôi vì nó được định nghĩa bên ngoài cơ thể lớp học nhưng phạm vi với CCObject.

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

Câu hỏi 2

Trong lớp cocos2d-x CCMenuItem, nó đã là một phương pháp nhà máy tĩnh định nghĩa dưới đây

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

Vì vậy, điều này typedef có nghĩa là khi tôi vượt qua một chức năng nó , Tôi đi qua giá trị với một con trỏ? Làm thế nào sẽ C + + xử lý này nếu chức năng không được thông qua bởi con trỏ. Là một hàm được xử lý như một đối tượng với một hàm tạo bản sao?

Tôi đánh giá cao mọi trợ giúp và lời khuyên. Cảm ơn

Trả lời

6

void (CCObject::*)(CCObject*) là một phương pháp con trỏ loại (một loại con trỏ tới thành viên), không phải là một con trỏ hàm thông thường. Đó là một con trỏ có thể trỏ đến một phương thức thể hiện của lớp CCObject có tham số là loại CCObject*. Kiểu của lớp là một phần của kiểu con trỏ (ký hiệu là CCObject::), tương tự như tham số (vì bên dưới, con trỏ tới "đối tượng hiện tại" là tham số ẩn cho tất cả các phương thức mẫu, this).

typedef chỉ cần định nghĩa SEL_MenuHandler làm từ đồng nghĩa cho loại con trỏ phương thức đó.

Để sử dụng một con trỏ phương pháp, bạn cần phải cung cấp cả một thể hiện để hoạt động như this, cũng như các đối số, bằng cách sử dụng cú pháp như thế này:

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

Làm thế nào sẽ C++ xử lý này nếu chức năng không được chuyển qua con trỏ. Chức năng có được xử lý như một đối tượng với một hàm tạo bản sao không?

Trong C/C++, không thể có biểu thức "loại chức năng" hoặc "loại phương thức". Bất cứ lúc nào bạn cố gắng để có được một cái gì đó của "loại chức năng", nó sẽ được tự động chuyển đổi thành một loại "con trỏ đến chức năng".

+0

Cảm ơn, điều này hữu ích –