V1053. Calling the 'foo' virtual function in the constructor/destructor may lead to unexpected result at runtime.


Анализатор обнаружил вызов виртуальной функции в конструкторе или деструкторе класса:

struct Base
{
  Base()
  {
    foo();
  }
  
  virtual ~Base() = default;
  virtual void foo() const;  
};

Сам по себе вызов виртуального метода 'foo' в конструкторе класса 'Base' может не являться ошибкой, однако проблемы могут проявить себя в производных классах.

struct Child : Base
{
  Child() = default;

  virtual ~Child() = default;
  virtual void foo() const override;
};

Во время создания объекта типа 'Child' будет вызван метод 'Base::foo()' из конструктора базового класса, но не переопределенный метод 'Child::foo()' из производного класса. Отметим, что в некоторых других языках программирования (C#, Java, ...) аналогичный код будет работать иначе: во время создания объекта 'Child' конструктором по умолчанию будет вызван конструктор по умолчанию базового класса 'Base', который затем вызовет переопределенный метод 'Child::foo()'.

Для исправления этой проблемы нужно уточнить вызов метода. Например, для класса 'Base':

struct Base
{
  Base()
  {
    Base::foo();
  }
  
  virtual ~Base() = default;
  virtual void foo() const;  
};

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

Также отметим, что использование указателя на себя 'this' при вызове виртуального метода не решает исходную проблему, и при использовании 'this' все также необходимо уточнить, из какого класса следует позвать виртуальную функцию:

struct Base
{
  Base()
  {
    this->foo();       // bad
    this->Base::foo(); // good
  }
  virtual ~Base() = default;
  virtual void foo() const;  
};

Найденные ошибки

Проверено проектов
381
Собрано ошибок
13 764

А ты совершаешь ошибки в коде?

Проверь с помощью
PVS-Studio

Статический анализ
кода для C, C++, C#
и Java

goto PVS-Studio;