C ++, когда использовать & перед функцией перегрузки оператора - PullRequest
3 голосов
/ 06 июня 2019

Когда вам нужно использовать & перед объявлением оператора?

Пример:

class ClassName {
     public:
        // Some constructor here..

        ClassName operator+(...)
        ClassName operator*(...)
        ClassName &operator+=(...) < has an &
        ClassName operator==(...)
        ClassName &operator<<(...) < has an &
     private:
        // Some member variables here..
}

Когда вы хотите различить постфикс и префикс i++ или ++i вы используете &

ClassName &operator++()
ClassName operator++(int)

Но когда вы используете & для других функций перегрузки оператора?Есть какое-то правило или это как-то связано с памятью?

Ответы [ 2 ]

8 голосов
/ 06 июня 2019

tl; dr: То же, что и с любой функцией.Возвращаете ли вы по значению или по ссылке?


Возможно, будет понятнее, если вы выровняете амперсанд по левому краю (что не имеет смыслового эффекта, как при char* str против * 1007).*):

ClassName& operator++()
ClassName operator++(int)

Таким образом, выбор зависит от того, хотите ли вы вернуть ссылку на существующий объект:

ClassName& operator++()
{
    this->someMember += 1;
    return *this;
}

… или новый приятный:

ClassName operator++(int)
{
    // Post-fix operator so we have to return the "old" unmodified version
    ClassName old = *this;
    this->someMember += 1;
    return old;
}

В первом случае возврат по значению может сбить пользователя с толку ++, поскольку:

  • была ненужная копия и
  • дальнейшие операциина результат ++ не повлияет на исходный объект.

Во втором случае возврат по ссылке будет bad , потому что:

  • это будет свисающая ссылка на локальную переменную.
6 голосов
/ 06 июня 2019

Когда вам нужно использовать & перед объявлением оператора?

Символ & объявляет тип возвращаемого значения функции как ссылку.Более конкретно, ссылка на lvalue.Таким образом, вы используете &, когда хотите вернуть ссылку lvalue, и не используете &, когда хотите вернуть ссылку без ссылки.

Итак, когда вы хотите вернуть ссылку из-за перегрузки оператора?Краткое практическое правило заключается в том, что вы должны возвращать ссылку, если встроенный оператор для не относящихся к классу типов является выражением lvalue, и возвращать не-ссылку, если встроенный оператор является выражением rvalue.Есть исключения из этого.Например, иногда вы не можете вернуть ссылку.Возможно, вам нужно вернуть какой-то объект-обертку, который ведет себя как ссылка;такие оболочки обычно возвращаются по значению.

Операторы присваивания, включая составные операторы присваивания, такие как +=, обычно возвращают ссылку на *this.

Оператор Postfix условно возвращает предыдущее значение.Таким образом, он не может вернуть ссылку на *this, которая содержит текущее значение.Префиксный оператор возвращает текущее значение, поэтому он может возвращать ссылку.Приращение префикса объекта, не относящегося к классу, является выражением lvalue, поэтому возвращение lvalue (т. Е. Ссылки) из перегрузки оператора является хорошим соглашением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...