开发者

How to overload operator +() for a class

The following is a class that contains a operator+ method. I understand the feetInches::operator+(const feetInches &other) const part of it but in the method definition, why is there an extra feetInches and what does it represent here?

   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开发者_JS百科+(const feetInches &other) const    
   {
      feetInches temp;
      temp.feet = feet + other.feet;
      temp.inches = inches + other.inches;
      return temp;
   }


Declaring a function const means you can't modify the this object (unless of course you try to modify mutable fields, but that's a different story). Therefore, to return something which is the sum of two feetInches, you must create a new feetInches object and return that.

// 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:

As a comparison, consider overloading operator +=:

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

Because in this case the this object is changed, the operator is no longer constant. You also operate on members of this, not a temporary object. On return, you return a reference to this.


shouldn't it be:

 feetInches temp = *this; 


The temp feetInches is the object you return from the addition. It's the result.


The operator + must return a new object. The temp object is this new object.


Note this is a const function. Its members can't modified. Therefore a temp object is used to hold the result.


The semantics of an operator+ in C++ are to add 2 objects together and return a brand new result, without modifying either of the objects you are adding. The extra temp instance is that brand new result.


You are implementing binary operator+, the definition of which takes two elements (untouched) and generates a third element with the result of the addition. The reason for the extra feetInches object in the code is that you don't want to modify the left hand side object. As of understanding the operator, maybe it could be simpler if you considered the implementation:

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

The original code just splits that single statement into 4 different statements: construction of the object (must be a named variable to be used later), setting the two fields, and returning the object.

Alternatively, the recommended approach to operator overloading would be slightly different:

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;
}

As of the reasons:

  • Flexibility: Allows for operator+ and operator+= with a single implementation
  • Type symmetry: Allows the compiler to perform implicit conversions in both operands
    • 1 + obj, obj + 1 will both work with that single implementation, in the member function approach, 1 + obj cannot be resolved by the compiler, as it cannot convert the first element before calling the member function
  • Efficiency: Taking the first argument by value means that temporaries used as first argument can be optimized away.

Note that in the modified version there are still three objects: the original left hand side, the copy as first argument of operator+ that gets returned and the right hand side, we have not removed the object. Also, this implementation for this particular type requires an extra copy in the operator+ return statement (the copy from the argument to the return value cannot be elided), but for more complex types that can be moved, the return statement will move the contents of the object.

More on operator overloading here

[*] This is a design decision, operator+= can be implemented as a free function, but it can be argued (at least I do) that semantically += is an operation of the first argument.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜