Перегрузка оператора, оператор + против оператора + =

Я читал некоторый исходный код C ++, и я подошел к некоторому синтаксису.

path& path::operator+=(string postPath)

и мне было интересно, является ли это фактическим синтаксисом и почему c ++ не использует уже существующий оператор + вместо этого в сочетании с применением значения к рассматриваемому объекту.

Это как, если вы хотите убедиться, что объект удаляется правильно. Но деструктор должен разобраться со всем этим.

-Edit1

Я знаю, что есть разница между a + = b; и А + В;
Мне было интересно, почему c ++ не просто использует оператор + с + = вместо того, чтобы переопределять оператор + = так же, как оператор +

-Edit2

Я не уверен, что все получилось правильно, но я спрашивал, почему язык не выводит + = на основе +.
И теперь я понимаю, другие применения + =. Спасибо всем 🙂

2

Решение

  1. Там могут быть проблемы эффективности; если ваш объект дорогой для копирования / назначения, a+=b потенциально спасает вас временную конструкцию, конструкцию копии и назначение, и позволяет вам лучше использовать ресурсы, которые у вас уже есть в целевом объекте. Если std::vector был += Оператор конкатенации векторов, было бы гораздо эффективнее реализовать его напрямую (вы можете использовать дополнительную емкость целевого объекта и избежать бесполезного распределения) вместо создания временного вектора суммы (который начинается «с нуля») и его назначения.

    На самом деле, обычно я реализую + с точки зрения +=обычно это дает код, который является одновременно более эффективным и простым для написания; как это:

    T &operator+=(const T &r)
    {
    // say that T encapsulates an N-dimensional array
    for(int i=0; i<N; ++i)
    arr+=r.arr[i];
    return *this;
    }
    
    T operator+(const T &r)
    {
    T ret(*this);
    ret+=r;
    return ret;
    }
    

    (хотя я согласен, что было бы неплохо иметь возможность попросить компилятор синтезировать +/- от существующих операторов; то же самое для реляционных операторов)

  2. Вы можете захотеть иметь объект, который может быть добавлен, но не может быть скопирован / назначен. Например, для моего игрушечного проекта я кратко рассмотрел наличие перегруженных сигнальными объектами (например, boost или Qt, или .NET events / multicast делегаты), которые перегружены += добавить соединение (Signal &operator+=(std::function<T...> fn)), но я не хотел иметь дело с семантикой назначения / копирования (что IMHO для сигнала не имеет смысла);

  3. В основе всего этого лежит общая идея, что в C ++ вы можете перегружать (почти) все операторы, чтобы они делали что угодно, без особых ограничений семантики. Вы можете написать operator+ который запускает ракету и operator+= это удаляет все файлы на вашем жестком диске — вы отвечаете, если в вашем приложении есть смысл, вы можете делать это без особых ограничений.

6

Другие решения

С ++ делает нет предположения относительно перегруженных операторов; вы можете
определить operator+ который не является коммутативным, например. а вы
может определить operator+= который не имеет никакого отношения к operator+,
Вы также можете определить operator+= без определения operator+ или порок
наоборот.

Что касается того, почему: для начала, вы действительно не хотите, чтобы компилятор предполагал
тот operator+ на строки является коммутативным, и, следовательно, оптимизировать.
И однажды открыв дверь, авторы языка не сомневаются
чувствовал, что лучше оставить это на усмотрение программиста, а не
навязывать что-либо на уровне языка. Даже если я не могу придумать случай
могут быть случаи, когда имеет смысл поддержать += а также
+ с немного другой семантикой. Общая философия C ++
всегда должен был дать программисту все инструменты, которые ему необходимы для
писать хороший код, но не запрещать код, который не соответствует текущему
Идея о том, что плохой код. (В конечном итоге это окупилось, так как
наши идеи относительно того, что является хорошим и плохим кодом, развивались.)

6

Да, path& path::operator+=(string postPath); действует и перегружает += оператор для случая, когда string добавляется на path,

Причина, по которой вы хотите иметь возможность перегрузки, проста: operator+ должен вернуть новое значение вместо того, чтобы изменить старое, в то время как operator+= может повторно использовать существующий ресурс (например, выделенную память). Поскольку основной операцией добавления строк (то, что вы делаете) является выделение памяти, += может быть значительно более производительным в вашем конкретном случае.

Кроме того, операция SomePath + SomeString ставит вопрос о SomeString + SomePathи, что еще хуже, SomeStringA + SomePathB, которые все немного отличаются, в то время как SomePath += SomeString имеет очень четкое значение.

Так как теперь должно быть ясно, почему вы хочу быть в состоянии реализовать += без реализации +рассмотрим другое направление: почему бы просто не использовать a = a + b в качестве реализации по умолчанию для a += b:

Во-первых, правила перегрузки операторов старше = delete, Следовательно, это правило всегда триггер, даже в тех случаях, когда вы делаете не хочу operator+= существовать вообще. Обратите внимание, что реализация «по умолчанию» очень проста:

A& operator+=(A const& other) { return *this = *this + other; }
1

почему C ++ не использует уже существующий оператор +, а в сочетании с применением значения

Именно потому что += мутирует и + не делает. Это часто подразумевает значительные различия в реализации.

0

Внедрение a += b как a = a+b будет менее эффективным, чем его непосредственная реализация, поскольку ему придется создавать и уничтожать временный объект, назначенный a,

Это более эффективно для реализации + с точки зрения +=

path operator+(path prePath, string postPath) {
return prePath += postPath;
}

С философской точки зрения, можно утверждать, что менее удивительно, если язык магически не генерирует операторов, которых вы не ожидаете. Многие люди обнаруживаются неявно сгенерированными конструкторами и операторами присваивания, дающими своим типам неверную семантику копирования (пока они не изучат Правило трех), и другое магическое поведение может вызвать замешательство в других отношениях.

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector