Я читал о семантике перемещения в C++, и в объяснениях люди дают много аналогов, чтобы упростить его, и в моей голове все, что я вижу, это то, что люди называют «движущимся», а не «копированием», это всего лишь мелкая копия объекта и установка любых указателей в объекте «перемещенный из» на нуль. Это в основном суть? Неглубоко копировать и устанавливать указатели других на нуль?Перемещение семантики только мелкой копии и установка указателей других на нуль?
ответ
Неверная копия и указание других указателей на нуль?
Мелкая копия - да. Указание других указателей на нуль - не всегда.
Минимальное требование состоит в том, что перемещенный объект находится в «неопределенном, но действительном состоянии», что означает, что вы можете переназначить его, перенести его или удалить, не вызывая отказ программы, но выполнить никакая другая зависящая от государства операция на нем. Это означает, что в целом вполне реально реализовать назначение переноса в терминах std::swap
.
Некоторые объекты определяют более сильный контракт. Один из них - std::unique_ptr
. Перемещение - из одного из них приведет к тому, что оно содержит null
, но это явно задокументировано.
Перемещение семантики только мелкой копии и установка указателей других на нуль?
Это может быть, если указатели, равные нулю, удовлетворяют инварианту класса. То есть: если объект с нулевыми указателями является допустимым состоянием.
Итак, я бы дал более подробное описание: Переместить конструктор и оператор присваивания выполнить мелкую копию и очистить перемещенную из объекта в состояние, которое удовлетворяет инварианту класса.
Также помните, что в случае назначения перемещения вы должны помнить, что обрабатывать указатель, который будет перезаписан копией ласточки.
Если класс принадлежит, например, заостренным объектам, инвариант требует, чтобы ни один из двух объектов не принадлежал одному и тому же объекту. Есть по крайней мере три способа реализации этого:
- Установите указатель на нуль
- Построить новый объект
- свопа указателей с перемещенным на объект (в случае перемещения конструктора, это по существу то же самое как один из предыдущих вариантов, поскольку указатель первоначально неинициализирован, если только одно из предыдущих не было выполнено, но с назначением перемещения это удобно позаботится об объекте, ранее указанном перемещенным объектом).
Иногда необходимо также установить данные об отсутствии ресурсов, такие как поле size
или аналогичные для соответствия новому состоянию объекта, если этого требует инвариант. Существуют и другие ресурсы, которые могут храниться в объекте, а также должны быть очищены, кроме того, что они содержат указатели на память, например файловые дескрипторы.
В значительной степени это. Вы понимаете, почему все в порядке? – StoryTeller
Хорошо, потому что удаление nullpointer совершенно безопасно в C и C++ (я проверил), а когда объект «переместился с», уничтожен, вы не уничтожаете ресурс дважды. Я просто борюсь со всем этим новым материалом C++. – Zebrafish
Речь идет не только о указателях, которые нужно удалить. Речь идет о ресурсах в целом (например, потоки, дескрипторы файлов, соединения с БД ...) – juanchopanza