Диагностическое правило основано на руководстве MISRA (Motor Industry Software Reliability Association) по разработке программного обеспечения.
Правило актуально только для C++.
Анализатор обнаружил, что переопределяющая виртуальная функция задаёт аргументы по умолчанию, отличающиеся от значений в функции базового класса. Такой код может являться ошибочным. Проблема заключается в том, что выбор аргументов по умолчанию происходит на этапе компиляции, а выбор самой виртуальной функции — на этапе выполнения. Из-за этого полиморфный вызов через базовый класс приведёт к неожиданному поведению: выполнится реализация из наследника, но со значениями по умолчанию из родительской версии.
Рассмотрим пример некорректного кода:
class Base
{
public:
virtual void print(int value = 10);
};
class Derived : public Base
{
public:
void print(int value = 20) override;
};
void foo(Base* b)
{
b->print();
}
В функции print в базовом классе параметр value имеет значение по умолчанию 10, а в производном классе значение по умолчанию изменено на 20. При вызове функции через указатель базового класса Base* компилятор подставит значение 10, но выполнит код функции Derived::print. Чтобы исправить ошибку, необходимо либо полностью убрать значения параметров по умолчанию в переопределяющей функции, либо сделать их строго идентичными значениям в базовом классе.
Исправленный вариант:
class Base
{
public:
virtual void print(int value = 10);
};
class Derived : public Base
{
public:
void print(int value) override;
};
void foo(Base* b)
{
b->print();
}
Была ли полезна эта страница документации?
Мы ответим вам на:
Если вы так и не получили ответ, пожалуйста, проверьте, отфильтровано ли письмо в одну из следующих стандартных папок: