Недавно я узнал о семантике перемещения C++11, поскольку изначально был программистом на C, который заботился о производительности, и мне было очень интересно изучить такую ​​важную функцию оптимизации. Мне пришлось просмотреть множество статей, объясняющих rvalues, lvalues ​​ и оператор &&. Я считаю, что вам все еще нужно изучить эти темы, чтобы выработать четкое понимание темы, но, с моей точки зрения, семантику перемещения можно объяснить интуитивно, проведя сходство между ней и моделью выполнения объектов Python.

Цель семантики перемещения — избежать ненужного копирования больших объектов при их передаче из одной функции в другую.

Как объекты передаются в python?

Интересно, что Python был создан с учетом именно этой оптимизации.

Во-первых, важно понимать тонкую разницу между интерпретацией следующего оператора в Python и C++.

В C++ переменная str создается в памяти, это место в памяти содержит носитель данных, а str ссылается на это место в памяти.

Однако в питоне история другая. Хотя этот оператор также создает объект с тем же содержимым, но str не является ссылкой на объект. str — это просто имя, и оператор привязывает его к объекту. Это тонкое отклонение может показаться не столь важным, но оно имеет большое значение при передаче аргументов в функцию.

Рассмотрим следующие 2 фрагмента кода

В первом фрагменте создается неизменяемый объект, содержащий данные "medium" и str, привязанный к этому объекту. Когда вызывается метод modify, новое имя arg также привязывается к 'medium', но как только выполняется строка 2, привязка arg перемещается в другой новый объект с данными 'hard', потому что невозможно изменить неизменяемый. Результирующее поведение выглядит как обычный вызов передачи по значению.

С другой стороны, поведение, показанное во втором фрагменте, напоминает вызов передачи по ссылке, поскольку modifyздесь не выполняет повторную привязку arg к новому объект, потому что этот объект является изменяемым. arg и l — два имени, привязанных к одному и тому же объекту. При выполнении строки 2 этот объект модифицируется.

В python ссылки на объекты передаются по значению,другими словами, объекты перемещаются.

Семантика перемещения С++ с точки зрения непрофессионала

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

Семантика перемещения основана на ссылках rvalue. rvalue появляется справа от оператора присваивания. Пример rvalue может быть средним здесь:

Также функция getName() может возвращать rvalue, поскольку оно появляется в правой части оператора.

имя является ссылкой rvalue.

Мне нравится думать о rvalue как об объекте Python, а о ссылке rvalue как об имени, привязанном к этому объекту. Разница в том, что значение r не может существовать само по себе, в то время как python полагается на сборку мусора для очистки объектов, которые больше не привязаны к какой-либо области.

Без конструктора перемещения последнее назначение строки будет

  • выделить память для временного объекта (и уничтожить его позже)
  • снова выделить память в месте назначения

Добавление конструктора перемещения к определению объекта оптимизирует второе выделение и повторно использует предыдущее выделение для места назначения.

Вывод

Имея в голове эту аналогию, понять силу семантики ходов было не сложнее. Когда для объекта определен конструктор перемещения, можно будет повторно привязать его к другому имени, избегая дорогостоящих копий.

Ресурсы







Урок № 5: Семантика перемещения
Семантика перемещения обеспечивает способ «перемещения
содержимого объектов между объектами, а не копирования, таким образом…mbevin .wordpress.com»