Операторы назначения перемещения и копирования должны либо перемещать, либо соответственно копировать базовые классы и представители данных класса без каких-либо побочных эффектов
Операторы назначения перемещения и копирования должны либо перемещать, либо соответственно копировать базовые классы и представители данных класса без каких-либо побочных эффектов.
Когда вы используете операторы назначения move и copy, вы ожидаете, что операция перемещает или копирует исходный объект в целевой объект, не создавая никаких побочных эффектов. Если операторы переноса или копирования назначения класса создают побочные эффекты, инвариант объекта может измениться во время переноса или копирования назначений. Рассмотрим этот код, где несколько объектов класса C
копируются друг другу.
class C{ //... C& operator=(const C& oth) { value = oth.value / 2; return *this; } public: int value; }; int main(){ C a, b, c; a.value = 48; // … b = a; // b.m = 24 c = b; // c.m = 12 a = c; // a.m = 6 }
value
в целевом объекте становится половина value
в исходном объекте. После трех последовательных операций копирования, a.value
становится 6
, что неожиданно. Алгоритмы ожидают перемещения и копирования операторов назначения, которые не изменяют инвариант объекта. Если у операторов переноса или копирования класса есть побочные эффекты, которые изменяют инвариант объекта, использование библиотек алгоритмов, таких как стандартная библиотека шаблонов (STL), может привести к неожиданным результатам.Поскольку вы много раз используете назначения move и copy в коде, любой побочный эффект, создающий код, может сделать код медленнее и ресурсоемким. В операторе назначения перемещения код, который вызывает побочные эффекты, может также заставить компилятор использовать операцию копирования с каждым назначением, что неэффективно.
Для поддержания оптимальной и надежной эффективности во время переезда и копирования выполните только эти операции в операторах переезда и копирования:
Копирование или перемещение представителей данных и базовых классов.
Верните указатель *this
.
Если возможно, установите объект moved-from в допустимое состояние.
Избегайте лишнего кода, который добавляет несвязанные побочные эффекты или накладную эффективность.
В теле оператора копирования или перемещения назначения Polyspace® не помечает эти операции:
Копирование или перемещение назначений.
Реляционные или сравнительные операции.
Изменение исходного объекта в операции перемещения.
Вызовы функции std::swap
или эквивалентные пользовательские noexcept
функции swap. Polyspace идентифицирует функции, которые эти сигнатуры как функции свопа: void T::swap(T&)
или void [N::]swap(T&, T&)
. Первая сигнатура представляет представителю функцию T
классов это принимает один аргумент. Вторая сигнатура представляет часть или статическую функцию в пространстве имен
N
это принимает два аргумента. Имя swap
может быть нечувствительным к регистру и префиксированным или постфиксированным подчеркиванием.
Назначение и изменение static
переменные.
Polyspace помечает любые другие операции в операторе копирования или перемещения назначения как нежелательный побочный эффект. Например, вызов пользовательской функции swap рассматривается как нежелательный побочный эффект, если функция swap не noexcept
. Для аналогичного правила копирования и перемещения конструктора смотрите AUTOSAR C++14 Rule A12-8-1
.
Если вы ожидаете нарушения правил, но не видите его, обратитесь к разделу «Стандартные нарушения кодирования не отображаются».
Группа: Операторы |
Категория: Необходимый, Автоматизированный |