MFC的消息地图,不需要&?

时间:2011-08-31 06:58:21

标签: c++ pointers mfc

我一直在寻找这个问题的答案,但似乎很难得到它,这最终将我带到了这里。

这是我们必须把&在指向成员函数的指针之前。 例如这里。

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之前, 下面的每一行都很完美。

  1. ON_COMMAND(ID_APP_ABOUT,CSingleApp :: OnAppAbout)//&amp;
  2. ON_COMMAND(ID_APP_ABOUT,&amp; CSingleApp :: OnAppAbout)// no&amp;
  3. 我试图找到原因,我很好奇是否因为static_cast&lt;&gt;但事实证明,static_cast与它无关。

    所以我想知道为什么在VS2008中我有2个选择我把&amp;或者我不必把&amp;。

2 个答案:

答案 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 ++编译器总是更加轻松,并且允许语言中通常不允许的内容,例如在从类的上下文中形成指针时离开限定符,而不需要使用&是严格要求的。