Действительно ли требуется проверка самопредставления при реализации оператора присваивания перемещения для класса?

Type &Type::operator=(Type &&rhs)
{
if(this == &rhs) //is there any need of self-assignment . 
returh *this ;
}
...
}

// поскольку он будет вызываться по r-значению, так почему же самостоятельное назначение??

1 ответ

Обычно...

Предположим, ваш класс содержит указатель на некоторый буфер, который он выделяет. Теперь в наивном операторе присваивания перемещений вы бы:

  • Освободи свой собственный буфер
  • Назначьте указатель буфера другого объекта на указатель буфера
  • Присвойте нуль указателю буфера другого объекта и, возможно, установите его размер равным 0

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

... но не всегда

Существует (узкое) исключение из вышеприведенного правила: случай, когда ваш оператор перемещения назначается "идемпотентом" для самостоятельного назначения. Например, если ваш оператор присваивания включает только присваивание членов - тогда можно назначать самопредставление точно так же, как обычное присваивание (полагая, что реализации самопредставления членов верны). Ничто не будет изменено или потеряно.

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

Другие вопросы по тегам