Почему в учебнике используется список инициализаторов в качестве возвращаемого значения оператора- (комплекса а)? - PullRequest
0 голосов
/ 09 июля 2019

Я читаю учебник (Бьярна Страуструпа) определения класса complex

class complex {
    double re, im; // representation: two doubles
public:
    complex(double r, double i) :re{r}, im{i} {} // construct complex from two scalars
    complex(double r) :re{r}, im{0} {}           // construct complex from one scalar
    complex() :re{0}, im{0} {}                   // default complex: {0,0}

    double real() const { return re; }
    void ral(double d) { re = d; }
    double imag() const { return im; }
    void imag(double d) { im = d; }

    complex& operator+=(complex z) { re+=z.re, im+=z.im; return *this; } // add to re and im
                                                                         // and return the result
    complex& operator-=(complex z) { re-=z.re, im-=z.im; return *this; }


    complex& operator*=(complex); // defined out-of-class somewhere
    complex& operator/=(complex); // defined out-of-class somewhere
};

В книге также определяются операции комплекса:

complex operator+(complex a, complex b) { return a+=b; }
complex operator-(complex a, complex b) { return a-=b; }
complex operator-(complex a) { return {-a.real(), -a.imag()}; } // unary minus
complex operator*(complex a, complex b) { return a*=b; }
complex operator/(complex a, complex b) { return a/=b; }

Я не понимаютретья строка выше, которая имеет дело с одинарным минусом.Почему имеет смысл использовать список инициализаторов в качестве возвращаемого значения operator-(complex a);?

Ответы [ 3 ]

4 голосов
/ 09 июля 2019

Вы должны иметь

return {-a.real(), -a.imag()};

потому что вы хотите вернуть complex, созданный из этих двух значений. Если вы пытались использовать

return -a.real(), -a.imag();

вместо этого вы бы вернули complex, который был создан из -a.imag(), так как оператор запятой возвращает только последнее значение. По сути, код точно такой же, как

return -a.imag();

Чтобы сделать это более явным, автор мог бы написать

return complex{-a.real(), -a.imag()};
//or
return complex(-a.real(), -a.imag());

но это действительно не нужно, поскольку возвращаемое значение всегда преобразуется в тип возвращаемого значения, а со списками инициализаторов они используются так же, как вы ввели return_type{ initializers }.

2 голосов
/ 09 июля 2019

Без списка инициализатора вы должны написать

complex operator-( complex a ) { return complex( -a.real(), -a.imag() ); }

Со списком инициализатора определение оператора выглядит проще.

В любом случае компилятор выбирает конструктор

complex( double, double );

Учтите, что в общем случае функция должна быть объявлена ​​как

complex operator-( const complex &a ) { return { -a.real(), -a.imag() }; }
1 голос
/ 09 июля 2019

Тип возврата этой функции - объект complex, поэтому эти параметры в списке инициализатора выводятся как параметры для конструктора complex, и возвращается новый объект.

...