Программирование на C ++: как ссылки работают при перегрузке операторов? - PullRequest
0 голосов
/ 28 января 2020

Я пытаюсь понять, почему ссылки используются при перегрузке оператора C ++. Например, в следующем фрагменте кода:

GenericObject& operator=(const GenericObject &rhs)
{
    if (&rhs == this)
        return *this;
    objectAttribute = GenericObject.objectAttribute;
    return *this;
}

У меня есть три вопроса:

  1. Почему функция возвращает ссылку?
  2. Почему функцию взять в ссылку? Чтобы избежать затрат на копирование содержимого объекта (что было бы необходимо, если бы объект GenericObject был параметром вместо ссылки на GenericObject)?
  3. Почему ссылка используется в третьей строке, когда сравнивая правую сторону с этим?

1 Ответ

0 голосов
/ 28 января 2020

В меру своих возможностей, ответы на ваши вопросы:

  1. Вы возвращаете ссылку, потому что она спасет вас позже в вызовах конструктора / деструктора. Хорошее эмпирическое правило, которым пользуется мой профессор, гласит: «Если сомневаешься, делай так, как делают его». Когда вы смотрите на операцию, подобную int x = 1, y = 2, z = 3; x = y = z;, возврат по ссылке позволяет вам принять значение z, присвоить его y, а затем принять значение (новое) y и присвоить его x. Для возврата по значению необходимо создать копию z, использовать ее для назначения y, удалить копию z, а затем создать копию (нового) y для назначения x перед удалением эта копия. Может не иметь большого значения для целых чисел, но это может означать гораздо более длинную программу с большими данными.

  2. Вы абсолютно правы! По тем же причинам, по которым мы пытаемся сэкономить время и усилия в первой части, мы передаем правый элемент по ссылке, чтобы не создавать дубликаты (для которых требуются вызовы конструктора / деструктора) и сделать их const, поэтому что мы не можем случайно изменить его, поскольку это нелогично с operator=. В качестве дополнительного примечания, дополнительные вызовы конструктора / деструктора могут быть опасны, если вы не будете осторожны в некоторых ситуациях (см. Пример глубокие копии против мелких копий ).

  3. Когда вы делаете вызов, например x = y;, он логически эквивалентен x.operator=(y);. Поскольку x - это некоторый объект, нам нужен способ ссылки на все это, а ключевое слово this позволяет эту функцию. this - это указатель, поэтому, поскольку мы пытаемся сравнить указатель и объект, нам нужно указать на объект, содержащий rhs (или y в моем примере), и мы получаем этот адрес с помощью &.

...