Недавно я узнал о семантике перемещения 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 полагается на сборку мусора для очистки объектов, которые больше не привязаны к какой-либо области.
Без конструктора перемещения последнее назначение строки будет
- выделить память для временного объекта (и уничтожить его позже)
- снова выделить память в месте назначения
Добавление конструктора перемещения к определению объекта оптимизирует второе выделение и повторно использует предыдущее выделение для места назначения.
Вывод
Имея в голове эту аналогию, понять силу семантики ходов было не сложнее. Когда для объекта определен конструктор перемещения, можно будет повторно привязать его к другому имени, избегая дорогостоящих копий.
Ресурсы
Ссылки на rvalue и семантика перемещения в C++ для начинающих
В моей предыдущей статье «Понимание значения lvalue и rvalue в C++ я имел возможность объяснить самому себе…www .internalpointers.com»
Урок № 5: Семантика перемещения
Семантика перемещения обеспечивает способ «перемещения содержимого объектов между объектами, а не копирования, таким образом…mbevin .wordpress.com»