Какие проблемы может вызвать предупреждение C4407? - PullRequest
5 голосов
/ 27 сентября 2011

Я получил несколько предупреждений, используя чисто виртуальные интерфейсы на некоторых объектах, производных от MFC CWnd, посредством множественного наследования. Я считаю, что это вызвано определением методов, которые должны быть реализованы для карты сообщений.

warning C4407: cast between different pointer to member representations, compiler may generate incorrect code

Это звучит немного больше, чем предупреждение, больше похоже на то, что может привести к повреждению кучи. Так есть ли другой способ сделать что-то похожее на приведенное ниже, что не приведет к тому, что динамические макросы MFC будут задыхаться больше, чем обычно?

class ISomeInterface
{
public:
     virtual LRESULT OnSomeRegisteredMessage(WPARAM wp, LPARAM lp) = 0;
};

class CSomeCoolWnd : public CWnd, public ISomeInterface
{
public:
     LRESULT OnSomeRegisteredMessage(WPARAM wp, LPARAM lp);
};

BEGIN_MESSAGE_MAP(CSomeCoolWnd , CWnd)
     ON_REGISTERED_MESSAGE(WM_USER_DEFINED, &CSomeCoolWnd::OnSomeRegisteredMessage)
END_MESSAGE_MAP()

Единственное, что я придумал, это закомментировал обработчики сообщений из интерфейсов и оставил комментарии, говорящие потребителю, что они должны его реализовать. Однако было бы неплохо применить это через ошибку компилятора, а не позволять им использовать интерфейс и получать неожиданные результаты во время выполнения из-за отсутствия вещей.

Ответы [ 2 ]

4 голосов
/ 27 сентября 2011

Отличное описание различных представлений значений указателя на член можно найти в статье Указатели на функции-члены и максимально быстрые делегаты C ++ . По сути, все разные типы наследования могут требовать использования разных представлений указателя на функцию-член. Это зависит от компилятора, и в статье рассказывается о нескольких различных компиляторах (до 2005 года, когда статья была написана).

Очевидно, что для использования множественного наследования с виртуальными функциями может потребоваться представление, отличное от простой функции указателя на член. Вероятно, где-то в ON_REGISTERED_MESSAGE() есть приведение, которое не видно в коде, который вы опубликовали.

1 голос
/ 04 декабря 2012

Попробуйте использовать что-то вроде этого:

class ISomeInterface
{
public:
     virtual LRESULT OnSomeRegisteredMessage(WPARAM wp, LPARAM lp) = 0;
};

class CSomeCoolWnd : public CWnd, public ISomeInterface
{
public:
     LRESULT OnSomeRegisteredMessage(WPARAM wp, LPARAM lp);
};

typedef void (CSomeCoolWnd::*FNMETHOD) (WPARAM, LPARAM);
FNMETHOD method = &CSomeCoolWnd::OnSomeRegisteredMessage;

BEGIN_MESSAGE_MAP(CSomeCoolWnd, CWnd)
     ON_REGISTERED_MESSAGE(WM_USER_DEFINED, method)
END_MESSAGE_MAP()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...