operators (Помогите разобраться)

Модератор: Модераторы разделов

Аватара пользователя
kkkggg
Сообщения: 100

operators

Сообщение kkkggg »

class complex
{
double re,im;
public:
complex (double r, double i):re®,in(i) {} // (**)
complex operator+ (complex);
complex operator* (complex);
};

int main ()
{
complex a = complex(1,3,1);
complex b = complex(1.2,2);
complex c = b;

a = b+c;
b = b+c*a;
c = a*b+complex(1,2);

return 0;
}

Почему не работает, пример выдрал их "Бьерн Страуструп специальное издание" страница 310
c++ пишет: undefined reference to `complex::operator+(complex)'
Обратите внимание на строку с коментарием **, что значит :re®,in(i) ?
Спасибо сказали:
Michael
Сообщения: 92

Re: operators

Сообщение Michael »

kkkggg писал(а):
04.06.2006 12:00
Почему не работает, пример выдрал их "Бьерн Страуструп специальное издание" страница 310
c++ пишет: undefined reference to `complex::operator+(complex)'

Нет определения функции complex::operator+

kkkggg писал(а):
04.06.2006 12:00
Обратите внимание на строку с коментарием **, что значит :re®,in(i) ?

re®,im(i) - значит, что re присваивается знаение r, а im - значение i.
Спасибо сказали:
Аватара пользователя
Zeus
Сообщения: 694

Re: operators

Сообщение Zeus »

Так а где реализации операторов-то? Объявления есть, а реализации?
И ещё как говорится "замеченные опечатки":
- в этой же строке (**) должно быть не in(i), а im(i)
- где создаётся объект a конструктору передаётся почему-то 3 параметра.
Видимо подразумевается, что вместо одной из запятых должна быть точка?
Спасибо сказали:
Аватара пользователя
kkkggg
Сообщения: 100

Re: operators

Сообщение kkkggg »

[quote name='Zeus' post='211954' date='Jun 4 2006, в 12:28']
Так а где реализации операторов-то? Объявления есть, а реализации?
И ещё как говорится "замеченные опечатки":
- в этой же строке (**) должно быть не in(i), а im(i)
- где создаётся объект a конструктору передаётся почему-то 3 параметра.
Видимо подразумевается, что вместо одной из запятых должна быть точка?
[quote]

Это всё опечатки и все мои, на быструю руку набивал

[quote]
re®,im(i) - значит, что re присваивается знаение r, а im - значение i.
[quote]

А чем плохо "re = r, im = i"?
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: operators

Сообщение v04bvs »

В данном случае это ничем не хуже, но вообще говоря вместо double может быть ваш собственный тип с конструктором, которому нужны параметры, и такой синтаксис - единственный вариант создать объект, используя конструктор не по умолчанию. А в этом случае просто для унификации кода.
Спасибо сказали:
Аватара пользователя
Zeus
Сообщения: 694

Re: operators

Сообщение Zeus »

На сколько я понимаю, если делать так как в примере, то при конструировании этих double'ов используется копирующий конструктор.
А так как ты написал - сначала отработает конструктор по-умолчанию, а потом вызовется оператор присваивания.
Дольше, короче.

PS: И реализацию-то всё-таки не забудь добавить :)
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: operators

Сообщение v04bvs »

Для простых типов вроде int и double конструктор по умолчанию не вызывается, т.е. по умолчанию в них мусор после инициализации. Поэтому не дольше.
Спасибо сказали:
Аватара пользователя
Zeus
Сообщения: 694

Re: operators

Сообщение Zeus »

Даже у автоматических переменных?
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: operators

Сообщение v04bvs »

Zeus писал(а):
04.06.2006 21:28
Даже у автоматических переменных?

Что такое автоматические переменные?
Я имею ввиду, что если есть код типа

Код: Выделить всё

struct A { int a; };
struct B { int a; B() : a() {} };

int main( )
{
    A a;
    B b;
    std::cout << a.a << " " << b.a << std::endl;
}

то первым числом выведется мусор, а вторым 0.
Спасибо сказали:
Аватара пользователя
Zeus
Сообщения: 694

Re: operators

Сообщение Zeus »

Автоматическая переменная это как-раз это a и b.
Раньше насколько помню для таких переменных встроенных типов компилятор обеспечивал начальное значение 0.
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: operators

Сообщение v04bvs »

Zeus писал(а):
05.06.2006 18:22
Автоматическая переменная это как-раз это a и b.
Раньше насколько помню для таких переменных встроенных типов компилятор обеспечивал начальное значение 0.

Ну может быть..
Сейчас посмотрел в стандарт, вот что говорят:

(standard) писал(а):12.6.2.4
If a given nonstatic data member or base class is not named by a mem-initializer-id (including the case
where there is no mem-initializer-list because the constructor has no ctor-initializer), then
— If the entity is a nonstatic data member of (possibly cv-qualified) class type (or array thereof) or a base
class, and the entity class is a non-POD class, the entity is default-initialized (8.5). If the entity is a non-
static data member of a const-qualified type, the entity class shall have a user-declared default construc-
tor.
— Otherwise, the entity is not initialized. If the entity is of const-qualified type or reference type, or of a
(possibly cv-qualified) POD class type (or array thereof) containing (directly or indirectly) a member of
a const-qualified type, the program is ill-formed.


Да и компилятор с ним согласен.
Спасибо сказали:
Аватара пользователя
kkkggg
Сообщения: 100

Re: operators

Сообщение kkkggg »

Бог ты мой, вопрос на 2,5 бала, а в какие дебри забрели.... :blink:
Ладно помогите пожалуйста определить вункцию complex::operator+, для данного примера. Первый раз связался с "operator", и пока не доходит...
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: operators

Сообщение v04bvs »

Код: Выделить всё

complex complex::operator+ (complex c)
{
    return complex(re + c.re, im + re.im);
}
Спасибо сказали:
Аватара пользователя
oav
Бывший модератор
Сообщения: 296

Re: operators

Сообщение oav »

v04bvs писал(а):
06.06.2006 09:39

Код: Выделить всё

complex complex::operator+ (complex c)
{
    return complex(re + c.re, im + re.im);
}

Господа адепты С++, ну-ка напишите насколько _плох_ такой "пример". УжОс просто :ph34r:

зы. для интереса добавьте в коструктор complex вывод какой-нить строчки и в конструктор копирования тоже и посмотрите вывод на консоль :)
Спасибо сказали:
Аватара пользователя
Zeus
Сообщения: 694

Re: operators

Сообщение Zeus »

Мне вообще приличный код operator+ видится с трудом.
Вроде лучше ссылку передать, а передавать ссылку на автоматическую переменную нельзя.
Тогда придётся динамически память выделять? А освобождать где? И неочевидно это для использующего этот оператор...
Лучше operator+= перегрузить :)
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: operators

Сообщение v04bvs »

Ну что было в первом посте, то я и написал. Конечно надо сделать конструктор преобразования, оператор определить отдельно от класса, использовать константные ссылки, но для автора вопроса, на мой взгляд, это будет несколько сложновато.
Спасибо сказали:
Аватара пользователя
Zeus
Сообщения: 694

Re: operators

Сообщение Zeus »

Что есть "конструктор преобразования"?
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: operators

Сообщение v04bvs »

Zeus писал(а):
06.06.2006 11:38
Мне вообще приличный код operator+ видится с трудом.
Вроде лучше ссылку передать, а передавать ссылку на автоматическую переменную нельзя.
Тогда придётся динамически память выделять? А освобождать где? И неочевидно это для использующего этот оператор...
Лучше operator+= перегрузить :)

А чем плох вариант

Код: Выделить всё

inline complex operator+( const complex &c1, const complex &c2 )
{
    return complex(c1.re() + c2.re(), c1.im() + c2.im());
}

Причём, насколько я помню, если писать
complex c = a + b
то даже лишнего вызова конструктора копирования может не быть.

Zeus писал(а):
06.06.2006 11:40
Что есть "конструктор преобразования"?

Код: Выделить всё

complex::complex( const float a_re ) :
    re_(a_re), im_(0)
{
}


и потом писать
complex c = 2;

Чтобы можно было писать такие штуки
complex a, b, c;
...
c = a + b;
a = c + 3;
b = 4 + a;
c = 2 + 3;

т.к. полностью интегрировать комплексное число и вещественное.
Спасибо сказали:
sdk
Бывший модератор
Сообщения: 210

Re: operators

Сообщение sdk »

А еще лучше так:

Код: Выделить всё

inline const complex operator+( const complex &c1, const complex &c2 )

Потому что, если без const, то можно делать такие вот непонятные штуки:
a+b = c
Серьезность - это способ сделать простые вещи сложными.
Если много знать - устанут глаза. Если много спать - то нет.
Нас никому не сбить с пути - нам пофигу куда идти.
:-)
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: operators

Сообщение v04bvs »

Действительно :-)
Даже не думал про это.
Спасибо сказали:
Аватара пользователя
Zeus
Сообщения: 694

Re: operators

Сообщение Zeus »

v04bvs писал(а):
06.06.2006 11:45
А чем плох вариант

Код: Выделить всё

inline complex operator+( const complex &c1, const complex &c2 )
{
    return complex(c1.re() + c2.re(), c1.im() + c2.im());
}

Я как-то с inline'ами особо не работал.
Как такой код будет работать?
Какова будет область видимости конструируемого complex'а?
Что сделает оператор return?

Причём, насколько я помню, если писать
complex c = a + b
то даже лишнего вызова конструктора копирования может не быть.

А где тут конструктор копирования?

Zeus писал(а):
06.06.2006 11:40

Что есть "конструктор преобразования"?

Код: Выделить всё

complex::complex( const float a_re ) :
    re_(a_re), im_(0)
{
}


А-а, надо ж. Я и не знал что оно так называется.

и потом писать
complex c = 2;

Чтобы можно было писать такие штуки
complex a, b, c;
...
c = a + b;
a = c + 3;
b = 4 + a;
c = 2 + 3;

т.к. полностью интегрировать комплексное число и вещественное.

А конструктор тут причём? Я думал тут операторы работают.
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: operators

Сообщение v04bvs »

Я как-то с inline'ами особо не работал.
Как такой код будет работать?
Какова будет область видимости конструируемого complex'а?
Что сделает оператор return?

Что то я ничего не понял.. inline это подсказка компилятору, что код функции маленький, и его желательно бы не выделять в отдельную функцию, а подставить в код. Что то вроде макроса. Хотя это только пожелание компилятору, он чего хочет, то и делает.
Будет работать обычно. Если вас смущает inline, можете его убрать, внешне ничего не изменится.
оператор return возвратит объект, сконструированный с помощью соотв. конструктора.
Можно так написать

Код: Выделить всё

complex temp(c1.re() + ..., ...);
return temp;

просто тот код короче.

А где тут конструктор копирования?

Ну компилятор может трактовать
complex c = a + b;
как
complex c(operator+(a, B)); // конструктор копирования
или как
complex c(a.re() + b.re(), a.im() + b.im()); // конструктора копирования нет

А конструктор тут причём? Я думал тут операторы работают.

Ну конечно можно наопределять операторов на каждый чих, вроде
operator+(const complex&, const complex&);
operator+(const complex&, float);
operator+(float, const complex&);

но проще определить только первый, и тогда вызов
c = 2 + a;
будет трактован как
c.operator=(operator+(complex(2), a));
т.е. компилятор достаточно умён, чтобы понять, что 2 можно преобразовать в complex с помощью конструктора преобразования, и потом результат подставить в operator+
Спасибо сказали:
Аватара пользователя
Zeus
Сообщения: 694

Re: operators

Сообщение Zeus »

v04bvs писал(а):
06.06.2006 13:20

Я как-то с inline'ами особо не работал.
Как такой код будет работать?
Какова будет область видимости конструируемого complex'а?
Что сделает оператор return?

Что то я ничего не понял.. inline это подсказка компилятору, что код функции маленький, и его желательно бы не выделять в отдельную функцию, а подставить в код.

Это-то я знаю. Получается в машинном коде никакого call-вызова собственно и не будет, тогда что будет делать return? И куда он будет "возвращать" сконструированный объект?

Что то вроде макроса. Хотя это только пожелание компилятору, он чего хочет, то и делает.
Будет работать обычно. Если вас смущает inline, можете его убрать, внешне ничего не изменится.
оператор return возвратит объект, сконструированный с помощью соотв. конструктора.

Ну и чем это тогда лучше первого предложенного тобой варианта?


А где тут конструктор копирования?

Ну компилятор может трактовать
complex c = a + b;
как
complex c(operator+(a, B)); // конструктор копирования
или как
complex c(a.re() + b.re(), a.im() + b.im()); // конструктора копирования нет
...
Ну конечно можно наопределять операторов на каждый чих, вроде
operator+(const complex&, const complex&);
operator+(const complex&, float);
operator+(float, const complex&);

но проще определить только первый, и тогда вызов
c = 2 + a;
будет трактован как
c.operator=(operator+(complex(2), a));
т.е. компилятор достаточно умён, чтобы понять, что 2 можно преобразовать в complex с помощью конструктора преобразования, и потом результат подставить в operator+

Что-то многовато компилятор "может трактовать".
Сейчас времени нет проверить, надо не забыть на досуге.
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: operators

Сообщение v04bvs »

Zeus писал(а):
06.06.2006 13:29
Это-то я знаю. Получается в машинном коде никакого call-вызова собственно и не будет, тогда что будет делать return? И куда он будет "возвращать" сконструированный объект?

Да, никакого call вызова не будет. И ретурна не будет. "Возвращать" он будет туда, куда написано в вызывающем коде.

Ну и чем это тогда лучше первого предложенного тобой варианта?

Тем, что параметр передаётся по ссылке, а не по значению (что помогает избежать, как на это намекал oav, ненужного копирования параметра). Так же есть небольшое отличие между определением оператора сложения как члена класса и как отдельной функции.

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

Что-то многовато компилятор "может трактовать".
Сейчас времени нет проверить, надо не забыть на досуге.

Ну в основном "может трактовать" относится к оптимизации. Т.е. может оптимизировать, может не оптимизировать.
Спасибо сказали:
Аватара пользователя
Zeus
Сообщения: 694

Re: operators

Сообщение Zeus »

v04bvs писал(а):
06.06.2006 13:43
Zeus писал(а):
06.06.2006 13:29

Это-то я знаю. Получается в машинном коде никакого call-вызова собственно и не будет, тогда что будет делать return? И куда он будет "возвращать" сконструированный объект?

Да, никакого call вызова не будет. И ретурна не будет. "Возвращать" он будет туда, куда написано в вызывающем коде.

Ну тогда он отличается от варианта без inline.
Потому что не будет конструироваться стековый объект который будет возвращаться из функции.


Ну и чем это тогда лучше первого предложенного тобой варианта?

Тем, что параметр передаётся по ссылке, а не по значению

А-а, блин, я и не заметил :)
Я-то всё смотрю когда появится ВОЗВРАТ не значения, а ссылки. И как он будет реализован :)


Что-то многовато компилятор "может трактовать".
Сейчас времени нет проверить, надо не забыть на досуге.

Ну в основном "может трактовать" относится к оптимизации. Т.е. может оптимизировать, может не оптимизировать.

По-моему ТАКИЕ вещи уже трудно отнести к оптимизации - слишком они принципиальные.
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: operators

Сообщение v04bvs »

Zeus писал(а):
06.06.2006 14:02
Ну тогда он отличается от варианта без inline.
Потому что не будет конструироваться стековый объект который будет возвращаться из функции.

почему не будет. Может и сконструироваться, это ничему не противоречит.
Если написано

Код: Выделить всё

inline Class foo() { return Class(1, 2, 3); }
...
v = foo();

то он может сделать что-то вроде

Код: Выделить всё

Class ret_value(1, 2, 3);
v = ret_value;

конечно это псевдокод. Но принцип примерно такой. Хотя здесь я лучше не буду ни о чём говорить, т.к. такие вещи для меня - тёмный лес. Единственное, в чём я уверен, проверить, "синлайнил" ли компилятор функцию или нет, можно только анализом ассемблерного кода.

Я-то всё смотрю когда появится ВОЗВРАТ не значения, а ссылки. И как он будет реализован :)

Ох, я не буду утверждать, что моё мнение - истина в последней инстанции, но я уверен, что возврат ссылки в случае отличном от реализации operator[] - ОЧЕНЬ большое зло. Кстати в книжке "Rules for C and C++ programming это совет 121, в Effective C++ - Item 31. Даже процитирую
Item 31: Never return a reference to a local object or to a dereferenced pointer initialized by new within the function.
This Item may sound complicated, but it's not. It's simple common sense. Really. Honest. Trust me.


По-моему ТАКИЕ вещи уже трудно отнести к оптимизации - слишком они принципиальные.

что конкретно вы имеете в виду? Единственный случай, когда оптимизация влияет на логику программы - return value optimization. (насколько мне известно) И это кстати то, что я имел ввиду, когда писал строчку

Код: Выделить всё

complex c(a.re() + b.re(), a.im() + b.im()); // конструктора копирования нет

Как я понимаю, это именно то место и та причина, где вам хотелось бы возвращать ссылку. Не нужно.
Спасибо сказали:
Аватара пользователя
Zeus
Сообщения: 694

Re: operators

Сообщение Zeus »

v04bvs писал(а):
06.06.2006 14:29
Zeus писал(а):
06.06.2006 14:02

Ну тогда он отличается от варианта без inline.
Потому что не будет конструироваться стековый объект который будет возвращаться из функции.

почему не будет. Может и сконструироваться, это ничему не противоречит.
Если написано

Код: Выделить всё

inline Class foo() { return Class(1, 2, 3); }
...
v = foo();

то он может сделать что-то вроде

Код: Выделить всё

Class ret_value(1, 2, 3);
v = ret_value;


Объект создастся 1 раз. Он же и присвоится.
А если создать объект в функции и вернуть его значение, то создастся ещё один объект в который скопируется значение автоматической (локальной - для данной функции) переменной и ЭТОТ объект вернётся вызывающему коду.


Я-то всё смотрю когда появится ВОЗВРАТ не значения, а ссылки. И как он будет реализован :)

Ох, я не буду утверждать, что моё мнение - истина в последней инстанции, но я уверен, что возврат ссылки в случае отличном от реализации operator[] - ОЧЕНЬ большое зло.

Ну зло - не зло, но его и реализовать-то красиво не удастся.
Ссылку на локальную переменную вернуть нельзя (как у тебя уже написано в цитате).
Динамическую переменную - коряво и почти никогда не соответствует семантике оператора. Т.е. тому, что от него ожидает другой программист.


По-моему ТАКИЕ вещи уже трудно отнести к оптимизации - слишком они принципиальные.

что конкретно вы имеете в виду? Единственный случай, когда оптимизация влияет на логику программы - return value optimization. (насколько мне известно)

Я не про влияние на логику говорю, а про "прозрачность" программы.
Чтобы по коду было понятно ЧТО ИМЕННО отработает в данной строке.
Чтобы объекты создавались только тогда, когда это нужно программисту.
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: operators

Сообщение v04bvs »

Zeus писал(а):
06.06.2006 15:10
Объект создастся 1 раз. Он же и присвоится.
А если создать объект в функции и вернуть его значение, то создастся ещё один объект в который скопируется значение автоматической (локальной - для данной функции) переменной и ЭТОТ объект вернётся вызывающему коду.

Покажи конкретную программу, где это демонстрируется.

Ну зло - не зло, но его и реализовать-то красиво не удастся.
Ссылку на локальную переменную вернуть нельзя (как у тебя уже написано в цитате).
Динамическую переменную - коряво и почти никогда не соответствует семантике оператора. Т.е. тому, что от него ожидает другой программист.

Можно статическую переменную =) Типа

Код: Выделить всё

complex& operator+(...)
{
    static complex result;
    result.re = ..;
    return result;
}

Можно какую-нибудь глобальную перемнную в анонимном namespace-е объявить. Способы то есть..

Я не про влияние на логику говорю, а про "прозрачность" программы.
Чтобы по коду было понятно ЧТО ИМЕННО отработает в данной строке.
Чтобы объекты создавались только тогда, когда это нужно программисту.

Всё равно не понял. Кажется мы про разные вещи говорим. Если объект создаётся тогда, когда это не нужно программисту, будут вызываться конструкторы и деструкторы => меняется логика программы.
Спасибо сказали:
Аватара пользователя
Zeus
Сообщения: 694

Re: operators

Сообщение Zeus »

v04bvs писал(а):
06.06.2006 15:26
Zeus писал(а):
06.06.2006 15:10

Объект создастся 1 раз. Он же и присвоится.
А если создать объект в функции и вернуть его значение, то создастся ещё один объект в который скопируется значение автоматической (локальной - для данной функции) переменной и ЭТОТ объект вернётся вызывающему коду.

Покажи конкретную программу, где это демонстрируется.

Конкретно - можно в код конструктора вставить какой-нибудь вывод.
А теоретически это следует вот из чего: область видимости локальной переменной - только функция, где она создана (там и умрёт). А что тогда вернётся "наверх", в вызывающий код?
По этой же причине нельзя возвращать ссылку на локальные (автоматические) переменные: к моменту их использования этих переменных уже нет.


Ну зло - не зло, но его и реализовать-то красиво не удастся.
Ссылку на локальную переменную вернуть нельзя (как у тебя уже написано в цитате).
Динамическую переменную - коряво и почти никогда не соответствует семантике оператора. Т.е. тому, что от него ожидает другой программист.

Можно статическую переменную =)
Можно какую-нибудь глобальную перемнную в анонимном namespace-е объявить. Способы то есть..

И всегда возвращать одну и ту же переменную?
Это как-раз то о чём я говорил: программист не рассчитывает на такое поведение оператора.
А способы наверное есть... Ну хотя бы пул переменных завести и возвращать их по-очереди, а когда кончатся - расширить пул. Прикинь изврат какой! :)


Я не про влияние на логику говорю, а про "прозрачность" программы.
Чтобы по коду было понятно ЧТО ИМЕННО отработает в данной строке.
Чтобы объекты создавались только тогда, когда это нужно программисту.

Всё равно не понял. Кажется мы про разные вещи говорим. Если объект создаётся тогда, когда это не нужно программисту, будут вызываться конструкторы и деструкторы => меняется логика программы.

Вот и не должно этого получиться в результате оптимизации.
Т.е. не должно быть неоднозначностей вроде описанных выше:
Ну компилятор может трактовать
complex c = a + b;
как
complex c(operator+(a, cool.gif); // конструктор копирования
или как
complex c(a.re() + b.re(), a.im() + b.im()); // конструктора копирования нет

По-моему этот код должен однозначно означать:
1. Создаётся объект c конструктором по-умолчанию.
2. Вызывается operator+ который создаёт промежуточный объект complex
3. Вызывается operator= которому передаётся объект complex (лучше - по-ссылке, а то создастся ещё один объект complex при вызове оператора).
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: operators

Сообщение v04bvs »

Zeus писал(а):
06.06.2006 15:54
Конкретно - можно в код конструктора вставить какой-нибудь вывод.

Я всё же настойчиво прошу пример и то, что он выведет.

Это как-раз то о чём я говорил: программист не рассчитывает на такое поведение оператора.
А способы наверное есть... Ну хотя бы пул переменных завести и возвращать их по-очереди, а когда кончатся - расширить пул. Прикинь изврат какой! :)

И самое интересное, что это всё зря =)


Ну компилятор может трактовать
complex c = a + b;
как
complex c(operator+(a, cool.gif); // конструктор копирования
или как
complex c(a.re() + b.re(), a.im() + b.im()); // конструктора копирования нет

По-моему этот код должен однозначно означать:
1. Создаётся объект c конструктором по-умолчанию.
2. Вызывается operator+ который создаёт промежуточный объект complex
3. Вызывается operator= которому передаётся объект complex (лучше - по-ссылке, а то создастся ещё один объект complex при вызове оператора).

ну 1 пункт - совсем не так, вообще говоря запись Type var = value; фактически эквивалентна Type var(value); просто для удобства. (для ясности замнём здесь вопрос об explicit конструкторах).

А остальное это конечно так, но это непроизводительно, а c++ хочет быть производительным на столько, сколько можно. поэтому даже порядок вычисления аргументов не определён. Хорошо это или плохо, не знаю, но это так, это просто надо знать и учитывать.

Кстати вот 12.2.2
(standard) писал(а):[Example:

Код: Выделить всё

     class X {
          // ...
     public:
          // ...
          X(int);
          X(const X&);
          ˜X();
     };
     X f(X);
     void g()
     {
          X a(1);
          X b = f(X(2));
          a = f(a);
     }

Here, an implementation might use a temporary in which to construct X(2) before passing it to f() using
X’s copy-constructor; alternatively, X(2) might be constructed in the space used to hold the argument.
Also, a temporary might be used to hold the result of f(X(2)) before copying it to b using X’s copy-
constructor; alternatively, f()’s result might be constructed in b. On the other hand, the expression
a=f(a) requires a temporary for either the argument a or the result of f(a) to avoid undesired aliasing of
a. ]
Спасибо сказали: