Карта сообщений MFC, нет необходимости &? - PullRequest
2 голосов
/ 31 августа 2011

Я искал ответ на этот вопрос, но мне кажется, что его довольно сложно получить, что приводит меня сюда наконец.

Это синтаксис, который мы должны поставить & вправо перед указателем на членфункция.Например, здесь.

class Test;
typedef void (Test::*fpop)();
class Test
{
public:
    void Op1(){}
};

int main(){
    fpop pFunc;
    pFunc = &Test::Op1;   // we must need the &

    return 0;
}

Однако, когда я смотрю на ON_COMMAND (или любые другие сообщения) в MFC, он кажется немного отличным от того, что я считаю правильным.

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 не имеет & before.

#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)

Более того, несмотря на отсутствие и memberFxn до и после, каждая строка ниже прекрасно работает.

  1. ON_COMMAND (ID_APP_ABOUT,CSingleApp :: OnAppAbout) // &
  2. ON_COMMAND (ID_APP_ABOUT, & CSingleApp :: OnAppAbout) // no &

Я попытался выяснить, почему, и мне было любопытно, может ли это бытьиз-за static_cast <> но оказалось, что static_cast не имеет к этому никакого отношения.

Поэтому мне интересно, почему в VS2008 у меня есть 2 варианта, где я помещаю & или мне не нужно ставить &.

Ответы [ 2 ]

4 голосов
/ 31 августа 2011

Компилятору 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 s или что-то, что подавляет ошибки, по причинам обратной совместимости. Более старые версии VC ++ были намного менее соответствующими, чем более новые компиляторы.

3 голосов
/ 31 августа 2011

Единственный правильный способ сформировать указатель на член в C ++ - использовать & и квалификатор класса (в данном случае CSingleApp::).

Компилятор Visual C ++ всегда был более расслабленным иразрешенные вещи, которые обычно не разрешены в языке, такие как выход из классификатора при формировании указателя из контекста класса и отсутствие необходимости использовать &, когда это строго требуется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...