Google Mock: издевательски перегруженные функции создают предупреждение C4373


Я издеваюсь над классом C++, который имеет 2 перегруженные функции, используя Google Mock и VS2010:

#include "stdafx.h"
#include "gmock/gmock.h"

#include "A.h"

class MockA : public A
{
public:
    // ...
    MOCK_METHOD3(myFunc, void(const int id, const int errorCode, const CString errorMsg));
    MOCK_METHOD1(myFunc, void(const CString errorMsg));
    // ...
};

Каждый раз, когда я компилирую, я получаю следующее предупреждение дважды:

1>c:devmy_projecttestsmocka.h(83): warning C4373: 'MockA::myFunc': virtual function overrides 'A::myFunc', previous versions of the compiler did not override when parameters only differed by const/volatile qualifiers
1>          c:devmy_projectmy_projectincludea.h(107) : see declaration of 'A::myFunc'

Есть идеи, почему?
Правильно ли это поведение?
Как мне этого избежать?

4 8

4 ответа:

Если это новый код, вы должны быть в порядке. Предупреждение C4373 говорит о том, что старые версии Visual Studio нарушили стандарт. Из связанной документации:

Версии компилятора до Visual C++ 2008 свяжет функцию с метод в базовом классе, затем выдайте предупреждающее сообщение. Последующий версии компилятора игнорируют const или volatile квалификатор, связывающий функция к методу в производном класс, затем выдать предупреждение C4373. Этот последнее поведение соответствует C++ стандарт.

Это было бы проблемой только в том случае, если бы вы нарушили код, основанный на неправильном поведении Visual Studio.

Для меня (в VS 2010) указание const на примитивных параметрах типа (которые, как я вижу, у вас также есть) вызвало такое поведение. Всякий раз, когда такое существовало в функции базового класса, которую я хотел переопределить, я не мог указать макет таким образом, чтобы это предупреждение не возникало; когда только у типа класса const value / const reference parameters, предупреждение никогда не возникало.

Поэтому мне кажется, что предупреждение в этом случае на самом деле является ошибкой компилятора (поскольку сигнатуры точно тот же).

Предлагаемый альтернативный подход:

#include "stdafx.h"
#include "gmock/gmock.h"

#include "A.h"

class MockA : public A
{
public:
    // ...

    void myFunc(const int id, const int errorCode, const CString errorMsg) {
      mocked_myFunc3(id, errorCode, errorMsg);
    }

    void myFunc(const CString errorMsg) {
      mocked_myFunc1(errorMsg);
    }

    MOCK_METHOD3(mocked_myFunc_3, void(const int id, const int errorCode, const CString errorMsg));
    MOCK_METHOD1(mocked_myFunc_1, void(const CString errorMsg));
    // ...
};

Я понимаю, что это старый вопрос, но поскольку я сам наткнулся на него сейчас, я хотел бы поделиться своим решением (или, по крайней мере, объяснением):

Проблема, скорее всего, заключается в том, что ваше объявление имеет параметр const, который будет игнорироваться компилятором. Именно определение может эффективно использовать const для параметра.

Теперь это также упоминается в Google mock faq теперь, чтобы избавиться от предупреждения, удалите const из параметра в объявление функции.

В моем случае мне было все еще трудно, так как реализация функции была для шаблонного класса внутри заголовка, где объявление и определение происходят одновременно. Решение этой проблемы, вероятно, заключается в отключении предупреждения при включении заголовка mocked class.