Рассмотрим следующее:
class Example : boost::noncopyable
{
HANDLE hExample;
public:
Example()
{
hExample = InitializeHandle();
}
~Example()
{
if (hExample == INVALID_HANDLE_VALUE)
{
return;
}
FreeHandle(hExample);
}
Example(Example && other)
: hExample(other.hExample)
{
other.hExample = INVALID_HANDLE_VALUE;
}
Example& operator=(Example &&other)
{
std::swap(hExample, other.hExample); //?
return *this;
}
};
Мое мышление здесь состоит в том, что деструктор будет работать на "другой" в ближайшее время, и поэтому мне не нужно снова реализовывать логику деструктора в операторе присваивания переходов с помощью swap. Но я не уверен, что разумное предположение. Будет ли это "хорошо"?
Ответ 1
Это должно быть хорошо, но это вряд ли лучше, чем рекомендуемая техника pass-by-value, и в этом случае конструктор перемещения будет использоваться в этой ситуации.
Ответ 2
Представьте себе следующее:
// global variables
Example foo;
struct bar {
void f() {
x = std::move(foo); // the old x will now live forever
}
Example x;
}
Аналогичная идиома, copy-and-swap (или в этом случае, move-and-swap), гарантирует, что деструктор запускается немедленно, что я считаю является лучшей семантикой.
Example& operator=(Example other) // other will be moved here
{
std::swap(hExample, other.hExample);
return *this;
} // and destroyed here, after swapping
Ответ 3
Мое мышление здесь в том, что деструктор будет работать на "другом" в ближайшее время
Тогда ваше мышление ошибочно. Вы можете перемещаться из любого объекта, к которому у вас есть неконстантный доступ. И объект может продолжать жить бесконечно после этого.
Технически правильно помещать ваши текущие данные в старый объект. Но это не очень хорошая идея. Лучше использовать переменную стека:
Example& operator=(Example &&other)
{
Example temp(std::move(other)); //other is now empty.
std::swap(hExample, temp); //our stuff is in `temp`, and will be destroyed
return *thisl
}
Или еще лучше (если вы не используете Visual Studio) храните свои вещи в оболочке, которая поддерживает движение правильно, и пусть конструктор перемещения сгенерированного компилятором выполнит эту работу для вас.