Понимание семантики перемещения стандарта C ++ - PullRequest
1 голос
/ 27 октября 2019

Я пытаюсь разобраться в семантике перемещения. Я запутался, потому что не мог понять, зачем нам это нужно и как мы должны его использовать идеально.

Например, когда мы перемещаем объект с помощью std :: move, он делает объект nullptr. почему это происходит? Кроме того, почему std :: move превращает объект в rvalue? Как это произошло? Почему после использования std :: move с переменной, он не заполняет его нулем, но когда я использую его с таким объектом, как вектор, после перемещения он заполняет его nullptr.

Надеюсь,кто-то объясняет семантику перемещения и другую семантику CPP шаг за шагом. Чем больше я об этом читаю, тем больше смущаюсь. Это одна из самых сложных тем программирования CPP.

1 Ответ

5 голосов
/ 27 октября 2019

Когда мы перемещаем объект с помощью std :: move

Нет. std::move не двигает вещами. Это дает нам выражение rvalue , ссылающееся на некоторый объект. Выражение rvalue приводит к функциям выбора разрешения перегрузки, которые принимают ссылки rvalue , что удобно, потому что теперь мы будемвыберите те из функций, которые принимают значения, или lvalue ссылки , которые традиционно выполняют функции, подобные копированию. Такие функции, как правило, являются конструкторами (так называемыми «конструкторами перемещения») или операторами присваивания (так называемыми «операторами присваивания перемещения»), потому что именно во время конструирования и назначения перемещение полезно.

itделает объект nullptr

Это полностью зависит от того, что делает упомянутая функция. Как правило, объект, который стоит переместить, имеет косвенное состояние, например указатель на некоторый динамически размещенный ресурс. И если указанный объект является перемещаемым, его конструктор перемещения лучше всего делать обмен на этих указателях. Если он не оставил указатель исходного объекта как nullptr, то у вас есть два объекта, владеющих ресурсом. Это был не ход;это была [мелкая] копия.

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

Кроме того, если все это звучит как хак, это потому, что он один. C ++ является мешаниной взлома, созданной на основе хаков, чтобы обеспечить дополнительную функциональность с течением времени. В этом случае нам понадобился (читай: wanted ) способ создания конструктора другого типа (и оператора присваивания), такого, который бы брал ссылку не const и мог модифицировать исходный объект. (чтобы «украсть» его ресурсы), и для достижения этого нам пришлось ввести новый тип ссылки, который связывал бы только с rvalues ​​ (потому что мы уже использовали все остальное для копий), а затем у нас быловвести функцию полезности, которая превратила бы имя объекта в rvalue … следовательно, родилась std::move, функция полезности, которая ничего не перемещает. ?

...