#20. Конструктор перемещения. Оператор присваивания перемещением | Уроки ООП C++
HTML-код
- Опубликовано: 13 апр 2024
- Практический курс по C/C++: stepik.org/course/193691/
Телеграм-канал: t.me/java_and_c
Инфо-сайт: proproprogs.ru/cpp_oop
Зачем нужен и как работает конструктор перемещения. Пример реализации и использования операции присваивания перемещением.
Спасибо. Качаем скилы!
Спасибо большое за твой труд друг!
💯
Top video
А можно ли освободить память у this->_data, а потом "this=&right;" и "right._data=nullptr;" в операторе присваивания перемещением?
В этом случае же, вроде, копируется адрес right и оператор присваивания копированием вызваться не должен?
Указателю this нельзя ничего присвоить, его нельзя изменить, он -- константный.
Здесь можно выполнить обмен полями данных length, capacity и data между right и объектом, для которого вызван перемещающий оператор присваивания.
Тогда, когда закончится вычисление выражения, в контексте которого был вызван перемещающий оператор присваивания, right будет уничтожен.
При уничтожении right в его деструкторе освободится та память, которая была в поле data объекта, для которого был вызван перемещающий оператор присваивания и которая сейчас освобождается прямо в этом самом перемещающем операторе присваивания.
Что ж, тяжеловато... Как я понял, смысл в том, что rvalue ссылки могут ссылаться на объекты, которые нельзя напрямую куда то сохранить. А для создания временных объектов это то, что нужно.
Нет, смысл в том, что rvalue-ссылки могут ссылаться только на rvalue.
Конструкторы копирования/перемещения перегружены, должен выбраться один из них.
Если при конструировании в качестве инициализирующего значения используется rvalue, будет выбираться конструктор перемещения, иначе -- конструктор копии.
То же самое и для оператора присваивания: они перегружены, и если справа от = используется rvalue, то выберется перемещающий оператор, иначе -- копирующий.
Поскольку rvalue вскоре будет уничтожен, его значение можно "портить", но так, чтобы потом его деструктор мог отработать без замечаний.
Поэтому можно "свистнуть" себе у rvalue память, адрес которой хранится в его поле data, а в его поле data подсунуть nullptr, чтобы его деструктор отработал правильно.
Таким образом, наш объект "завладевает" памятью, которой владел объект rvalue без выделения аналогичного блока памяти, копирования и освобождения исходного.
В этом суть выигрыша от "перемещения": скопировать значение указателя и занулить исходный -- значительно быстрее выделения новой памяти и копирования данных.