Ошибка времени компиляции C4407 - PullRequest
4 голосов
/ 22 января 2010

В нашем коде есть следующая структура класса

Class A: public CDialog, public Base1, public Base2
{
};

В реализации класса A мы имеем следующее:

BEGIN_MESSAGE_MAP( A, CDialog )
    ON_WM_SIZE()
END_MESSAGE_MAP()

Обратите внимание, что Base1 и Base2 не наследуются от CDialog или любых других классов MFC.

На VC6 компиляция прошла успешно. Но на VC9 мы получаем следующий код ошибки:

ошибка C4407: приведение между различными указателями на представления членов, компилятор может генерировать неправильный код .

Этот код ошибки указывает на местоположение ON_WM_SIZE.

Может кто-нибудь сказать мне решение. Заранее спасибо.

Gamer

Ответы [ 4 ]

5 голосов
/ 12 марта 2013

Я только что решил пример этой проблемы; нашел этот вопрос с помощью веб-поиска.

В моем случае у меня также был класс диалога, унаследованный от нескольких классов: CDialog и ConfigurationTab, который является внутренним интерфейсом. Предупреждение компилятора было отключено путем изменения:

class Foo : public ConfigurationTab, public CDialog

с:

class Foo : public CDialog, public ConfigurationTab

Мы обнаружили эту ситуацию, когда сбойное диалоговое окно вылетало в методе ON_BN_CLICKED при присваивании переменной DDX. Переменная DDX была загадочно неинициализирована в этой строке, когда мы были уверены, что она инициализирована.

2 голосов
/ 22 января 2010

У меня нет удобного установленного V9, но я вижу, что между VS6 и VC8 определение ON_WM_SIZE изменилось, чтобы быть семантически таким же, но гораздо более строгим в том, что он принимает. VC6 использовал приведения C, где VC8 использует приведения C ++, которые улавливают больше проблем.

Нам нужно было бы увидеть фактическое объявление от вашего класса метода OnSize, я думаю, чтобы иметь возможность определить, что здесь происходит не так.

1 голос
/ 22 января 2010

Просто догадываюсь, давно я не делал MFC, но похоже, что он запутался в вашем множественном наследовании

BEGIN_MESSAGE_MAP (класс, базовый класс)

расширяется до вызова метода в «классе», поэтому, поскольку A наследуется множественно, неизвестно, какой из них использовать, возможно, у вас есть один и тот же метод в нескольких базовых классах?

0 голосов
/ 01 марта 2018

в моем случае класс Base2 имеет виртуальный метод. например.

class Base2
{
 virtual void method(){};
}

и предупреждение появляется при использовании

Class A: public CDialog, public Base1, public virtual Base2
{
};

для определения класса А.

Если я удалю виртуальное ключевое слово здесь.

Class A: public CDialog, public Base1, public Base2
{
};

затем предупреждение исчезло. Обратите внимание, что я не удалил виртуальный в теле Base2. Просто в определении класса А.

Надеюсь, это поможет вам.

...