请教类函数指针问题。
先上马
.h文件:
typedefvoid (CControlBase::*ControlMouseEventCB)(CControlBase * pControlBase, int nMouseX, int nMouseY);
class CControlBase
{
public:
static enum MOUSE_EVENT_TYPE
{
MOUSE_EVENT_L_UP,
MOUSE_EVENT_L_DOWN,
MOUSE_EVENT_R_UP,
MOUSE_EVENT_R_DOWN,
MOUSE_EVENT_MOVE,
MOUSE_EVENT_MAX,
};
public:
CControlBase(CONTROL_TYPE eControlType);
virtual~CControlBase();
voidSetMouseEventCB(MOUSE_EVENT_TYPE eMouseEventType, ControlMouseEventCB pEventFuncCB);
voidActiveMouseEvent(MOUSE_EVENT_TYPE eMouseEventType, int nMouseX, int nMouseY);
virtual boolOnMouseLDown(int nMouseX, int nMouseY);
virtual boolOnMouseLUp(int nMouseX, int nMouseY);
virtual boolOnMouseRDown(int nMouseX, int nMouseY);
virtual boolOnMouseRUp(int nMouseX, int nMouseY);
virtual boolOnMouseMove(int nMouseX, int nMouseY);
protected:
CControlBase(const CControlBase & val);
CControlBase & operator=(const CControlBase & rhs);
protected:
MOUSE_EVENT_TYPEm_eMouseCurType;
ControlMouseEventCBm_pMouseEventFuncCB[MOUSE_EVENT_MAX];
};
.cpp文件
void CControlBase::SetMouseEventCB(MOUSE_EVENT_TYPE eMouseEventType, ControlMouseEventCB pEventFuncCB)
{
if(eMouseEventType < 0 || eMouseEventType >= MOUSE_EVENT_MAX)
return;
m_pMouseEventFuncCB[eMouseEventType] = pEventFuncCB;
}
void CControlBase::ActiveMouseEvent(MOUSE_EVENT_TYPE eMouseEventType, int nMouseX, int nMouseY)
{
if(eMouseEventType < 0 || eMouseEventType >= MOUSE_EVENT_MAX)
return;
if(m_pMouseEventFuncCB[eMouseEventType])
(*m_pMouseEventFuncCB[eMouseEventType])(this, nMouseX, nMouseY);
}
我在子类调用ActiveMouseEvent函数,但编译器在这里:
(*m_pMouseEventFuncCB[eMouseEventType])(this, nMouseX, nMouseY);
报错了。
error C2171: “*”:“ControlMouseEventCB”类型的操作数非法
error C2064: 项不会计算为接受 3 个参数的函数
谢谢 类 函数指针
[解决办法]
(this->*m_pMouseEventFuncCB[...])(...)
[解决办法]
Inside the C++ Object Model 4.4 节
有详细的解释。我这里给你摘抄一点
4.4 Pointer-to-Member Functions
In Chapter 3, we saw that the value returned from taking the address of a nonstatic data member is the byte value of the member's position in the class layout (plus 1). One can think of it as an incomplete value. It needs to be bound to the address of a class object before an actual instance of the member can be accessed.
The value returned from taking the address of a nonstatic member function, if it is nonvirtual, is the actual address in memory where the text of the function is located. This value, however, is equally incomplete. It, too, needs to be bound to the address of a class object before an actual invocation of the member function is possible. The object's address serves as the this pointer argument required by all nonstatic member functions.
Recall that the syntax of declaring a pointer-to-member function is
double // return type
( Point::* // class the function is member
pmf ) // name of pointer to member
(); // argument list
Thus one writes
double (Point::*coord)() = &Point::x;
to define and initialize a pointer to class member and writes
coord = &Point::y;
to assign a value to it. Invocation uses the pointer-to-member selection operators, either
( origin.*coord )();
or
( ptr->*coord )();
These are converted internally by the compiler to, respectively,
// Pseudo C++ Code
( coord )( & origin );
and
// Pseudo C++ Code
( coord )( ptr );
The pointer-to-member function declaration syntax and pointer-to-member selection operators serves literally as placeholders for the this pointer. (This is why static member functions, which are without a this pointer, are of type "pointer to function," not "pointer-to-member function.")
Use of a pointer to member would be no more expensive than a nonmember pointer to function if it weren't for virtual functions and multiple inheritance (including, of course, virtual base classes), which complicate both the type and invocation of a pointer to member. In practice, for those classes without virtual functions or virtual or multiple base classes, the compiler can provide equivalent performance. In the next section, I look at how support for virtual functions complicates support for pointer-to-member functions.