2012-02-29 5 views
2

С ++ У меня есть случай использования Если у меня есть 5 классов А, В, С, D, Е и их экземпляры как, B, C, D, E+ перегрузка операторов в

Если есть выражение a = b + c + d + e;

Каков порядок вызова оператора + и оператора =. Также будет создан временный объект.

Можете ли вы помочь мне

+1

Если вы перегружаете эти операторы, вы можете использовать отладчик или диагностический вывод для определения заказа. Что происходит, когда вы это делаете? –

ответ

2

+ левоассоциативен. = - правильный ассоциативный. Заказ будет

  • d + e делает временный de
  • de + c делает временную cde. Это делается вызовом оператора C класса +, принимающего аргумент любого класса, временным de является экземпляр.
  • cde + b делает временные bcde. Это делается путем вызова оператора B класса + с аргументом класса cde.
  • Значение bcde присваивается переменной a.

Temporaries здесь общий случай, это зависит от того, что вы на самом деле делаете с вашей перегрузкой, что произойдет. Класс слева от временного будет вызван с использованием этого временного аргумента, а не наоборот.

В то время как оценка идет слева направо при использовании +, фактическое вычисление идет в другую сторону.

+0

Итак, оператор класса D + будет называться первым, который подобен оператору + (E & e). Итак, основываясь на том, что он возвращает, скажем, объект D/E, этот оператор operator + будет называться ИЛИ должен быть вызван оператором класса C +? – mSO

+0

Да, это идет справа налево, и вы не можете быть уверены в временных записях, поскольку другие сказали, что это зависит от вашей реализации и используемого вами компилятора. Попробуйте использовать отладчик, это, вероятно, лучший способ увидеть его в действии! – Dervall

+0

Класс '' '' '' '' '' '' '' '' будет вызываться с типом возвращения времен. – Dervall

2
a = b + c + d + e; 

Выражение на r.h.s в = будет оцениваться первым, а затем = будет называться, чтобы назначить этот результат переменной на l.h.s.

Выражение на r.h.s будет оцениваться справа налево.

Проверить operator precedence.

Кроме того, отметим, что формирование временного в этом случае будет зависеть от:

  • реализации перегруженного оператора + &
  • Компилятор используется
+0

Просто примечание, но приоритет оператора ** не ** контролирует порядок вызова функций перегрузки оператора. (За исключением косвенно, здесь, поскольку приоритет создает зависимости операнда.) –

0

Полная ссылка here.

Добавления выполняются сначала, справа налево. Назначение является последним для выполнения. В зависимости от оптимизаций, не может быть каким-либо временное производством:

int x,y,z,k; 
    x = y = z = k = 3; 
    int l = x + y + z + k; 
    cout << l; 
00401000 mov   ecx,dword ptr [__imp_std::cout (402038h)] 
00401006 push  0Ch 
00401008 call  dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (40203Ch)] 
+0

Мне любопытно, как не может быть временного. Любая разумная реализация 'operator +' будет возвращать временную, и нет копии на временную, которая может быть отменена. Поэтому я думаю, что должно быть как минимум три временных. –

+0

@JamesKanze Я обновил свой ответ самым очевидным примером, о котором я мог думать. –

+0

Вы не можете определить, было ли временное или нет с 'int'. Мы говорим о пользовательском 'operator +' здесь, возвращая тип класса. (В противном случае вопрос о временных словах не имеет смысла.) –

0

Надеется, что это не домашнее задание

http://en.cppreference.com/w/cpp/language/operator_precedence

+ precedence is higher than = 

так + первым, и он читает слева направо

затем =, и он читает справа налево

Для временного объекта, извините, я не знаю об этом.

+0

nah! У меня есть проект, в котором я добавляю пользовательские математические объекты. Int, Complex Number, vector .... – mSO

+0

Я вижу. Для темп. объект, очевидно, если он является исходным gcc без оптимизации, b + c превращается в временный объект bc, а затем продолжает + d и т. д. Для расчета, если все переменные внутри вашего класса являются примитивными, вам не нужно перегружать любой оператор + или =, C++ позаботится о вас. в противном случае вам нужно самостоятельно обрабатывать логику «плюс» :) – Tommy

1

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

a = b + c + d + e; 

означает:

a = (((b + c) + d) + e); 

который становится:

a.operator=(operator+(operator+(operator+(b, c), d), e)); 

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

Как это происходит, в этом конкретном выражении зависимости операндов налагают строгий порядок.

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

+0

Вы уверены, что это правильно, я думал, что это было бы так, как если бы вы написали a = b + (c + (d + e)); как + является ассоциацией слева направо? Возможно, я ошибаюсь ... – jcoder

+0

@JohnB Производство - _additive-expression_: _additive-expression_ + _multiplicative-expression_. Поэтому в 'a + b + c',' a + b' уменьшается сначала. Это то, что я понимаю и левым ассоциативным: оператор слева сначала сгруппирован. (Это соответствует экспликации в Википедии тоже.) –

+0

это тоже ANSEER – mSO

0

Порядок выполнения не изменяется при перегрузке. Применяются обычные правила C++ для приоритетов операторов и операндов.

Смежные вопросы