Как перегрузить оператор + () для класса - PullRequest
0 голосов
/ 29 сентября 2011

Ниже приведен класс, содержащий метод operator+. Я понимаю feetInches::operator+(const feetInches &other) const часть этого, но в определении метода, почему есть дополнительный feetInches и что он представляет здесь?

   class feetInches {
      public:
         feetInches(int inFeet = 0, int inInches = 0);
         feetInches operator+(const feetInches &other) const;
         void print() const;
      private:
         int feet;
         int inches;
   };

   feetInches feetInches::operator+(const feetInches &other) const    
   {
      feetInches temp;
      temp.feet = feet + other.feet;
      temp.inches = inches + other.inches;
      return temp;
   }

Ответы [ 7 ]

3 голосов
/ 29 сентября 2011

Объявление функции const означает, что вы не можете изменить этот объект (если, конечно, вы не попытаетесь изменить поля mutable, но это другая история). Следовательно, чтобы вернуть что-то, равное сумме двух feetInches, необходимо создать новый объект feetInches и вернуть его.

// return type     scope resolution             parameter type
//      |                 |                           |
//      |                 |                           |
    feetInches        feetInches::operator+(const feetInches &other) const    
    {
//      return value - you can't modify this (because method is const), so you must create 
//           |       a third object
        feetInches temp;
        temp.feet = feet + other.feet;
        temp.inches = inches + other.inches;
        return temp;
    }

EDIT:

Для сравнения рассмотрим оператор перегрузки +=:

 feetInches& feetInches::operator+=(const feetInches &other) 
 {
    feet = feet + other.feet;
    inches = inches + other.inches;
    return *this;
 }

Поскольку в этом случае объект this изменяется, оператор больше не является константой. Вы также оперируете членами this, а не временным объектом. По возвращении вы возвращаете ссылку на это.

1 голос
/ 29 сентября 2011

не должно быть:

 feetInches temp = *this; 
0 голосов
/ 29 сентября 2011

Вы реализуете двоичный файл operator+, определение которого берет два элемента (нетронутыми) и генерирует третий элемент с результатом сложения.Причина дополнительного feetInches объекта в коде заключается в том, что вы не хотите изменять левый объект.Что касается понимания оператора, может быть, было бы проще, если бы вы рассмотрели реализацию:

feetInches operator+( feetInches const & other ) const {
   return feetInches( feet+other.feet, inches+other.inches );
}

Исходный код просто разбивает этот единственный оператор на 4 различных оператора: конструкция объекта (должна быть именованной переменной длябудет использоваться позже), устанавливая два поля и возвращая объект.

В качестве альтернативы рекомендуемый подход к перегрузке операторов может быть немного другим:

class feetInches {
   int feet, inches;
public:
   feetInches( int feet = 0, int inches = 0 ) 
      : feet(feet), inches(inches) {}

   // Implement += internally [*]
   feetInches& operator+=( feetInches const & rhs ) {
      feet += rhs.feet;
      inches += rhs.inches;
      return *this;
   }
};
// Implement + as a free function taking the first element by value:
feetInches operator+( feetInches lhs, feetInches const & rhs ) {
   lhs += rhs;       // Reuse += implementation, no need to repeat
   return lhs;
}

По причинам:

  • Гибкость: допускает operator+ и operator+= с одной реализацией
  • Симметрия типа: позволяет компилятору выполнять неявные преобразования в обоих операндах
    • 1 + obj, obj + 1 оба будут работать с этой единственной реализацией, в подходе функции-члена 1 + obj не может быть разрешен компилятором, так как он не может преобразовать первый элемент перед вызовом функции-члена
  • Эффективность: принятие первого аргумента по значению означает, что временные значения, используемые в качестве первого аргумента, могут бытьоптимизирован.

Обратите внимание, что в измененной версии все еще есть три объекта: исходная левая сторона, копия в качестве первого аргумента operator+, которая возвращается, и правая часть, мы имеемне удален объект.Кроме того, эта реализация для этого конкретного типа требует дополнительной копии в операторе возврата operator+ (копия из аргумента в возвращаемое значение не может быть исключена), но для более сложных типов, которые могут быть перемещены ,оператор возврата будет перемещать содержимое объекта.

Подробнее о перегрузке оператора здесь

[*] Это решение по проекту, operator+= может быть реализовано как свободная функция, но можно утверждать (по крайней мере, я так), что семантически += является операцией первого аргумента.

0 голосов
/ 29 сентября 2011

Семантика оператора + в C ++ состоит в том, чтобы добавить 2 объекта вместе и вернуть совершенно новый результат, не изменяя ни один из добавляемых вами объектов.Дополнительный экземпляр temp - это совершенно новый результат.

0 голосов
/ 29 сентября 2011

Обратите внимание, что это постоянная функция.Его участники не могут быть изменены.Поэтому для хранения результата используется временный объект.

0 голосов
/ 29 сентября 2011

Оператор + должен вернуть новый объект.Объект temp - это новый объект.

0 голосов
/ 29 сентября 2011

temp feetInches - это объект, который вы возвращаете из дополнения.Это результат.

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