Функция должна возвращать ссылку или объект? - PullRequest
3 голосов
/ 28 мая 2010

Давайте обсудим эти две функции:

  1. сложный & оператор + = (const T & val);
  2. сложный оператор + (const T & val);

Где "complex" - это имя класса, который реализует, например, комплексную переменную.

Итак, первый оператор возвращает ссылку, чтобы можно было написать a + = b + = c (что эквивалентно b = b + c; a = a + b;).

Второй оператор возвращает и objec (НЕ ССЫЛКА), если мы все еще можем написать a = b + c + d.

Кто мог бы объяснить мне этот нюанс? В чем разница между возвращением ссылки или объекта?

Ответы [ 5 ]

4 голосов
/ 28 мая 2010

Операторы присваивания поддерживают несколько приложений для одного и того же объекта:

(a += b) += c;

, что добавит b и c к a.Чтобы это работало, a += b должен возвращать ссылку на a.Оператор сложения, однако, не требует этого, поскольку выражение b + c + d не имеет побочного эффекта.Только последнее назначение a имеет побочный эффект.

1 голос
/ 28 мая 2010

В 1, a + = b, оператор + = изменяет a. Поэтому он может возвращать ссылку на себя, потому что a является правильным результатом операции.

Однако в 2. требуется новый объект, потому что a + b возвращает что-то, что не является a, поэтому возвращение ссылки на not будет правильным.

1 голос
/ 28 мая 2010

Поскольку complex& operator+=(const T& val); работает на this и потому что complex operator+(const T& val); должен создать новый временный объект для суммы.

Если бы вы возвращали объект из +=, он бы , вероятно, сделал бы то, что ожидал, но там могли бы быть некоторые дополнительные копии. Как вы упомянули, вы бы хотели бы такое поведение, если вы хотите связывать вызовы. Если вы вернули временное и написали (a += b) += c, ваше добавление c будет потеряно, когда оно будет уничтожено во временном.

Если бы вы возвращали ссылку из +, у вас была бы ссылка на временный объект, и ваша программа имела бы неопределенное поведение. Вы можете написать a=b+c+d, потому что b+c создает временный b1, а b1 + d создает временный b2, который затем присваивается a.

1 голос
/ 28 мая 2010

Нюанс в примерах, которые вы приводите, некоторым образом.

От оператора +, который вы ожидаете получить обратно значение, отличное от двух, с которыми вы начали: b + c не является ни b, ни c, это что-то еще. Таким образом, мы не можем возвращать ссылки ни на b, ни на c ... и если не считать размещения нового объекта в стеке, это будут единственные две, с которыми нам придется работать. Таким образом, мы должны вернуть значение.

И вы уже объяснили себе, почему оператор + = возвращает то, что он делает.

0 голосов
/ 28 мая 2010

В первом случае вы добавляете что-то к объекту слева, но значением выражения является объект слева. Таким образом, вы возвращаете что-то (обычно слева) по ссылке. Например:

cout << (a+=b)

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

if(...)
{
    T a = b + c;
    cout << a;
}
...