>
>
>
V703. It is suspicious that the 'foo' f…


V703. It is suspicious that the 'foo' field in derived class overwrites field in base class.

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

В качестве примера можно привести следующий некорректный код:

class U {
public:
  int x;
};

class V : public U {
public:
  int x;  // <=
  int z;
};

Данный код может быть опасен, поскольку теперь в классе V существует две переменных x: собственно 'V::x' и 'U::x'. Последствия, к которым это может привести, могут быть проиллюстрированы следующим кодом:

int main() {
  V vClass;
  vClass.x = 1;
  U *uClassPtr = &vClass;
  std::cout << uClassPtr->x << std::endl; // <=
  ....
}

Здесь будет произведена печать неинициализированной переменной.

Для исправления проблемы достаточно удалить объявление переменной в классе-наследнике. Корректный код приведён ниже:

class U {
  public:
  int x;
};

class V : public U {
  public:
  int z;
};

Существует некоторое количество спорных случаев, которые анализатором не считаются ошибочными:

  • поля имеют различный тип;
  • хотя бы одно из конфликтных полей объявлено как static;
  • поле в базовом классе объявлено как private;
  • используется приватное наследование;
  • поле раскрылось через define;
  • поле носит одно из особых имён наподобие "reserved" (такие имена указывают на то, что переменная на самом деле резервирует часть структуры класса в памяти на будущее).

Мы рекомендуем всегда проводить рефакторинг кода, где анализатор выдаёт предупреждение V703. Использование переменной с одним именем в базовом классе и в наследнике далеко не всегда является ошибкой. Но такой код очень опасен. Даже если сейчас программа корректно работает, в дальнейшем при модификации классов очень легко допустить ошибку.

Данная диагностика классифицируется как:

  • CERT-DCL01-C

Взгляните на примеры ошибок, обнаруженных с помощью диагностики V703.