Подтвердить что ты не робот

Избегайте предупреждения "Необязательный формальный параметр"

У меня есть суперкласс вроде этого:

class Parent
{
public:
    virtual void Function(int param);
};

void Parent::Function(int param)
{
    std::cout << param << std::endl;
}

.. и подкласс вроде этого:

class Child : public Parent
{
public:
    void Function(int param);
};

void Child::Function(int param)
{
    ;//Do nothing
}

Когда я компилирую файл подкатегория .cpp, я получаю эту ошибку

warning C4100: 'param' : unreferenced formal parameter

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

Спасибо.

4b9b3361

Ответ 1

В С++ вам не нужно указывать параметр, что вы не используете имя, чтобы вы могли просто сделать это:

void Child::Function(int)
{
    //Do nothing
}

Однако вы можете сохранить имя параметра в объявлении в файле заголовка посредством документации. Пустое утверждение (;) также не нужно.

Ответ 2

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

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

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

void CFooBar::OnLvnItemchanged(NMHDR *pNMHDR, LRESULT *pResult)
{
    UNREFERENCED_PARAMETER(pNMHDR);

В качестве альтернативы:

void CFooBar::OnLvnItemchanged(NMHDR* /* pNMHDR */, LRESULT *pResult)
{
    // Not using: pNMHDR

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

Windows SDK в WinNT.h определяет UNREFERENCED_PARAMETER() вместе с DBG_UNREFERENCED_PARAMETER() и DBG_UNREFERENCED_LOCAL_VARIABLE(). Все они оценивают одно и то же, но разница в том, что DBG_UNREFERENCED_PARAMETER() используется, когда вы начинаете, и ожидаете использовать этот параметр, когда код будет более полным. Когда вы уверены, что никогда не будете использовать параметр, используйте версию UNREFERENCED_PARAMETER().

У Microsoft Foundation Classes (MFC) есть аналогичное соглашение с более короткими макросами UNUSED() и UNUSED_ALWAYS().

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

Ответ 3

Другой метод, который вы можете использовать, если вы хотите сохранить имя параметра, - это преобразовать в void:

void Child::Function(int param)
{
    (void)param;   //Do nothing
}

Ответ 4

Как упоминал @Charles Bailey, вы можете пропустить имя параметра.

Однако в некоторых сценариях вам нужно имя параметра, так как в сборках отладки вы вызываете ASSERT() на нем, но в розничной сети он создает nop. Для этих сценариев есть удобный макрос (по крайней мере, в VС++:-)) UNREFERENCED_PARAMETER(), который определяется следующим образом:

#define UNREFERENCED_PARAMETER(x) x

Обратите внимание, что простой бросок @R Samuel Klatchko опубликован также работает, но я лично считаю его более читаемым, если код явственен, что это параметр unreferenced или простой необъяснимый подобный.

Ответ 5

Я бы использовал макрос для подавления предупреждаемого формального параметра:

#define UNUSED( x ) ( &reinterpret_cast< const int& >( x ) )

Это имеет следующие преимущества:

  • В отличие от #define UNUSED (x) (void) x, он не вводит необходимость в полном определении типа параметра, которое должно быть замечено там, где такая потребность не могла существовать раньше.
  • В отличие от #define UNUSED (x) & x, его можно безопасно использовать с параметрами, типы которых перегружают унарный и оператор.

Ответ 6

Pragma работает хорошо, так как ясно, что вы используете VS. Это предупреждение имеет очень высокий коэффициент шумового эффекта, учитывая, что неприменимые параметры очень распространены в интерфейсах обратного вызова и производных методах. Даже команды в Microsoft Windows, которые используют W4, устали от своей бессмысленности (были бы более подходящими для /Wall ) и просто добавили в свой проект:

#pragma warning(disable: 4100)

Если вы хотите облегчить предупреждение только для блока кода, окружите его с помощью

#pragma warning(push)
#pragma warning(disable: 4100)
void SomeCallbackOrOverride(int x, float y) { }
#pragma warning(pop)

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