Для получения триального ключа
заполните форму ниже
Team License (базовая версия)
Enterprise License (расширенная версия)
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

** На сайте установлена reCAPTCHA и применяются
Политика конфиденциальности и Условия использования Google.
Запросите информацию о ценах
Новая лицензия
Продление лицензии
--Выберите валюту--
USD
EUR
GBP
RUB
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

** На сайте установлена reCAPTCHA и применяются
Политика конфиденциальности и Условия использования Google.
Для получения лицензии для вашего открытого
проекта заполните, пожалуйста, эту форму
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

** На сайте установлена reCAPTCHA и применяются
Политика конфиденциальности и Условия использования Google.
Для получения лицензии для вашего открытого
проекта заполните, пожалуйста, эту форму
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

** На сайте установлена reCAPTCHA и применяются
Политика конфиденциальности и Условия использования Google.
Мне интересно попробовать плагин на:
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

** На сайте установлена reCAPTCHA и применяются
Политика конфиденциальности и Условия использования Google.
Ваше сообщение отправлено.

Мы ответим вам на


Если вы так и не получили ответ, пожалуйста, проверьте папку
Spam/Junk и нажмите на письме кнопку "Не спам".
Так Вы не пропустите ответы от нашей команды.

>
>
>
V1054. Object slicing. Derived class ob…
Сообщения PVS-Studio
Диагностики общего назначения (General Analysis, C++)
Диагностики общего назначения (General Analysis, C#)
Диагностики общего назначения (General Analysis, Java)
Диагностика микро-оптимизаций (C++)
Диагностика 64-битных ошибок (Viva64, C++)
Cтандарт MISRA
Стандарт AUTOSAR
Дополнительная информация
Оглавление

V1054. Object slicing. Derived class object was copied to the base class object.

13 Апр 2020

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

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

Другим фактом является то, что объект базового класса теряет информацию о полях производного класса, если конструктор копирования сгенерирован компилятором неявно (возможно даже и в случае определенного пользователем).

Рассмотрим следующий пример:

struct Base
{
  int m_i;
  Base(int i) : m_i { i } { }
  virtual int getN() { return m_i; }
};

struct Derived : public Base
{
  int m_j; 
  Derived(int i, int j) : Base { m_i }, m_j { j } { }
  virtual int getN() { return m_j; }
};

void foo(Base obj) { std::cout << obj.getN() << "\n"; }

void bar()
{
  Derived d { 1, 2 };
  foo(d);
}

При передаче переменной 'd' в функцию 'foo' произойдет копирование, а функция 'getN' будет вызвана из класса 'Base'.

Чтобы избежать проблем, связанных со срезкой типа, стоит использовать указатели/ссылки:

void foo(Base &obj) { std::cout << obj.getN() << "\n"; }

В этом случае копирования не произойдет, и 'getN' будет вызвана из класса 'Derived'.

Если срезка типа все же необходима, то желательно определить явную операцию, которая это делает. Это спасет читателей кода от путаницы:

struct Base
{
  ....
};

struct Derived : public Base
{
  ....
  Base copy_base();
  ....
};

void foo(Base obj);

void bar()
{
  Derived d { .... };
  foo(d.copy_base());
}

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

struct Base
{
  int m_i;
  int m_j;
  Base(int i, int j) : m_i { i }, m_j { j } { }
  int getI() { return m_i; }
  int getJ() { return m_j; }
};

struct Derived : public Base
{
  Derived(int i, int j) : Base(i, j) { }
  virtual int getN() { return m_j; }
};

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

  • CERT-OOP51-CPP
Этот сайт использует куки и другие технологии, чтобы предоставить вам более персонализированный опыт. Продолжая просмотр страниц нашего веб-сайта, вы принимаете условия использования этих файлов. Если вы не хотите, чтобы ваши данные обрабатывались, пожалуйста, покиньте данный сайт. Подробнее →
Принять