В чем разница между операторами присваивания в C++?

Ответ

В C++ существует базовый оператор присваивания = и семейство составных операторов присваивания (+=, -=, *=, /=, %=, <<=, >>=, &=, |=, ^=).

Семантическая разница:

  • x = y;Простое присваивание. Присваивает значение правого операнда (y) левому (x).
  • x += y;Составное присваивание. Эквивалентно x = x + y;, но записывается компактнее.

Техническая разница (особенно для пользовательских типов): Для встроенных типов (int, double) разницы в результате нет, но составные операторы могут быть эффективнее для сложных объектов, так как позволяют избежать создания временного объекта.

Пример с перегрузкой для пользовательского класса:

class Vector {
public:
    Vector& operator+=(const Vector& other) { // Составное присваивание
        // Модифицируем текущий объект напрямую.
        this->x += other.x;
        this->y += other.y;
        return *this; // Возвращаем ссылку на себя
    }
    // Обычный оператор сложения, реализованный через += (идиома copy-and-swap)
    Vector operator+(const Vector& other) const {
        Vector temp = *this; // Создаём копию
        temp += other;       // Используем уже реализованный +=
        return temp;         // Возвращаем новую копию
    }
private:
    double x, y;
};

int main() {
    Vector a, b, c;
    c = a + b; // Вызывает operator+, создаёт временный объект.
    a += b;    // Вызывает operator+=, работает напрямую с 'a', эффективнее.
    return 0;
}

Вывод: Составные операторы не только улучшают читаемость, но и зачастую являются более эффективной идиомой, особенно при проектировании классов.

Ответ 18+ 🔞

А, слушай, вот тебе наглядная история про операторы присваивания в C++. Представь, что у тебя есть переменная x. Есть два способа её изменить: тупо перезаписать или аккуратно добавить к тому, что уже есть.

Вот базовый оператор = — это как сказать: «Забудь всё, что было, теперь ты вот это». x = y; — и всё, хуй с горы, старое значение похерено, теперь x равно y. Просто и грубо.

А вот составные операторы, типа +=, -= — это уже хитрая жопа. x += y; — это как сказать: «Ко всему, что у тебя уже лежит в x, прибавь ещё y». По сути, это короткая запись для x = x + y;. Читается проще, и писать меньше — уже плюс.

Но самое интересное начинается, когда дело доходит до производительности, особенно с какими-нибудь своими классами. Для обычных int или double — да похуй, разницы в результате нет. Но вот представь, что у тебя есть класс Vector, который хранит координаты. Если ты реализуешь обычный оператор сложения +, то он обязан вернуть новый объект. Это значит: создаётся копия текущего объекта, к ней что-то прибавляется, и эта новая копия возвращается. Создание временного объекта — это лишняя работа, ебать колотить.

А вот составной оператор += работает по-другому. Он модифицирует текущий объект напрямую и возвращает ссылку на себя же. Никаких лишних копий! Поэтому для сложных типов a += b почти всегда эффективнее, чем a = a + b.

Смотри, как это выглядит в коде. Вот идиоматический пример:

class Vector {
public:
    // Составное присваивание. Работает с самим собой, эффективно.
    Vector& operator+=(const Vector& other) {
        this->x += other.x;
        this->y += other.y;
        return *this; // Возвращаем ссылку на себя
    }

    // Обычный оператор сложения. Реализуем его ЧЕРЕЗ += — это классика.
    Vector operator+(const Vector& other) const {
        Vector temp = *this; // Ёпта, вот она — создание копии!
        temp += other;       // Используем уже написанный +=
        return temp;         // Возвращаем новую копию
    }
private:
    double x, y;
};

int main() {
    Vector a, b, c;
    c = a + b; // Тут вызовется operator+, создастся временный объект.
    a += b;    // А тут вызовется operator+=, который работает напрямую с 'a'. Эффективнее, бля!
    return 0;
}

Вывод простой, чувак: составные операторы — это не просто синтаксический сахар для ленивых. Это часто более эффективная и грамотная идиома, особенно когда пишешь свои классы. Используй += вместо a = a + b, где это уместно — и компилятор, и память скажут тебе спасибо.