我一直在寻找这个问题的答案,但似乎很难得到它,这最终将我带到了这里。
这是我们必须把&在指向成员函数的指针之前。 例如这里。
class Test;
typedef void (Test::*fpop)();
class Test
{
public:
void Op1(){}
};
int main(){
fpop pFunc;
pFunc = &Test::Op1; // we must need the &
return 0;
}
但是,当我看一下MFC中的ON_COMMAND(或任何其他消息)时,它看起来与我认为正确的有点不同。
VS6.0没问题。它遵循正确的语法,如下所示。 你可以清楚地看到&在memberFxn之前。
#define ON_COMMAND(id, memberFxn) \ // VS6.0
{ WM_COMMAND, CN_COMMAND, (WORD)id, (WORD)id, AfxSig_vv, (AFX_PMSG)&memberFxn },
// ON_COMMAND(id, OnFoo) is the same as
// ON_CONTROL(0, id, OnFoo) or ON_BN_CLICKED(0, id, OnFoo)
但在VS2008中,它有点奇怪。没有&在memberFxn之前。
#define ON_COMMAND(id, memberFxn) \ // VS2008
{ WM_COMMAND, CN_COMMAND, (WORD)id, (WORD)id, AfxSigCmd_v, \
static_cast<AFX_PMSG> (memberFxn) },
// ON_COMMAND(id, OnBar) is the same as
// ON_CONTROL(0, id, OnBar) or ON_BN_CLICKED(0, id, OnBar)
此外,尽管事实上没有&amp;在memberFxn之前, 下面的每一行都很完美。
我试图找到原因,我很好奇是否因为static_cast&lt;&gt;但事实证明,static_cast与它无关。
所以我想知道为什么在VS2008中我有2个选择我把&amp;或者我不必把&amp;。
答案 0 :(得分:4)
Visual C ++编译器(VS2005和VS2008)需要一个&符号(&
)和完全限定名称,以按照C ++标准形成指向成员的指针,如下所示:
class Test
{
public:
void Foo() {}
void Bar()
{
void (Test::*ptr1)() = Foo; // C3867
void (Test::*ptr2)() = &Foo; // C2276
void (Test::*ptr3)() = Test::Foo; // C3867
void (Test::*ptr4)() = &Test::Foo; // OK
}
};
出于向后兼容性的原因,很可能MFC标头中有#pragma
个或者可以抑制错误的东西。与较新的编译器相比,旧版本的VC ++ 更不符合。
答案 1 :(得分:3)
在C ++中形成指向成员的指针的唯一正确方法是使用&
和类限定符(在本例中为CSingleApp::
)。
Visual C ++编译器总是更加轻松,并且允许语言中通常不允许的内容,例如在从类的上下文中形成指针时离开限定符,而不需要使用&
是严格要求的。