РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
689 of 815 menu

Перемещающее присваивание

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

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

Синтаксис

class_name& operator=(class_name&& other);

Пример

Давайте создадим класс, который управляет динамическим массивом, и реализуем для него перемещающее присваивание:

#include <iostream> #include <utility> using namespace std; class Array { private: int* data; size_t size; public: Array(size_t s) : size(s), data(new int[s]) { for (size_t i = 0; i < size; i++) { data[i] = 0; } } ~Array() { delete[] data; } Array(const Array& other) : size(other.size), data(new int[other.size]) { for (size_t i = 0; i < size; i++) { data[i] = other.data[i]; } } Array& operator=(const Array& other) { if (this != &other) { delete[] data; size = other.size; data = new int[size]; for (size_t i = 0; i < size; i++) { data[i] = other.data[i]; } } return *this; } Array& operator=(Array&& other) noexcept { if (this != &other) { delete[] data; data = other.data; size = other.size; other.data = nullptr; other.size = 0; } return *this; } void set(size_t index, int value) { if (index < size) { data[index] = value; } } int get(size_t index) const { return data[index]; } size_t getSize() const { return size; } }; int main() { Array a(3); a.set(0, 1); a.set(1, 2); a.set(2, 3); Array b(5); b = std::move(a); cout << "b size: " << b.getSize() << endl; cout << "b values: " << b.get(0) << " " << b.get(1) << " " << b.get(2) << endl; cout << "a size: " << a.getSize() << endl; return 0; }

Результат выполнения кода:

"b size: 3" "b values: 1 2 3" "a size: 0"

Пример

Давайте рассмотрим пример с классом, который управляет строкой:

#include <iostream> #include <cstring> #include <utility> using namespace std; class MyString { private: char* str; size_t len; public: MyString(const char* s) : len(strlen(s)), str(new char[len + 1]) { strcpy(str, s); } ~MyString() { delete[] str; } MyString(const MyString& other) : len(other.len), str(new char[other.len + 1]) { strcpy(str, other.str); } MyString& operator=(const MyString& other) { if (this != &other) { delete[] str; len = other.len; str = new char[len + 1]; strcpy(str, other.str); } return *this; } MyString& operator=(MyString&& other) noexcept { if (this != &other) { delete[] str; str = other.str; len = other.len; other.str = nullptr; other.len = 0; } return *this; } const char* c_str() const { return str; } size_t length() const { return len; } }; int main() { MyString s1("abcde"); MyString s2("12345"); s2 = std::move(s1); cout << "s2: " << s2.c_str() << endl; cout << "s2 length: " << s2.length() << endl; cout << "s1 length: " << s1.length() << endl; return 0; }

Результат выполнения кода:

"s2: abcde" "s2 length: 5" "s1 length: 0"

Смотрите также

  • оператор копирующего присваивания,
    который копирует ресурсы из одного объекта в другой
  • конструктор перемещения,
    который перемещает ресурсы при создании объекта
  • конструктор копирования,
    который копирует ресурсы при создании объекта
  • деструктор класса,
    который освобождает ресурсы при уничтожении объекта
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить