Reputation: 16896
Here 3 variations of the overloading of addition operator (+) are given.
Which variation should I use and why?
class MyClass {
int myInteger;
double myDouble;
public:
MyClass(int i, double d) {
myInteger = i;
myDouble = d;
}
// Variation - 1
//--------------
MyClass operator +(MyClass rhsObj) {
return MyClass(this->myInteger + rhsObj.myInteger, this->myDouble + rhsObj.myDouble);
}
// Variation - 2
//--------------
MyClass &operator +(MyClass &rhsObj) {
rhsObj.myInteger = this->myInteger + rhsObj.myInteger;
rhsObj.myDouble = this->myDouble + rhsObj.myDouble;
return rhsObj;
}
// Variation - 3
//--------------
MyClass &operator +(MyClass &rhsObj) {
this->myInteger = this->myInteger + rhsObj.myInteger;
this->myDouble = this->myDouble + rhsObj.myDouble;
return *this;
}
};
int main() {
MyClass objOne(10, 10.5);
MyClass objTwo(20, 20.5);
MyClass objThree = objOne + objTwo;
}
What should be the case of Assignment Operator (=)? Which variation should it use?
Upvotes: 3
Views: 310
Reputation: 141790
You really want variations on one and three here.
Users of MyClass
will expect it to follow The Principle of Least Astonishment and would never expect to see the right-hand-side modified as a result of addition. Using const
more will enforce this and will also serve as documentation. If you wish to modify the left-hand-side, use +=
. Like so:
// Plus: Modify neither the left nor the right
//--------------
MyClass operator +(const MyClass& rhsObj) const
{
return MyClass(myInteger + rhsObj.myInteger, myDouble + rhsObj.myDouble);
}
// Increment: Modify the left
//--------------
MyClass& operator +=(const MyClass& rhsObj)
{
myInteger += rhsObj.myInteger;
myDouble += rhsObj.myDouble;
return *this;
}
Demo: http://ideone.com/8oarA
Upvotes: 4
Reputation: 38163
Depends on what you need.
First, about you versions - obviously
Most likely, Variation - 1 is the most preferred.
Why? Because of the side effects. If you see an expression like:
a = b + c;
whatever is the type of a
, b
and c
, what you would think? I would think, that a
is the sum of b
and c
AND b
and c
are untouched, I mean - with the old values.
Suppose, for example:
a = 5;
b = 6;
c = a + b;
Would you expect, that a
or b
will become 11
after the sum? (which will happen if you chose variation 2 or 3). Of course, you cannot overload operator+
for int
, but it's just an easy and intuitive example.
One performance improvement: in your variation 1, instead of
MyClass operator+(MyClass rhsObj)
I would use
MyClass operator+(const MyClass& rhsObj)
This way you'll avoid one additional copy + you will tell the "client", using your code, that you don't change rhsObj
at all, but just use its value.
Upvotes: 10
Reputation: 13356
There are subtle differences between these three +
's
The first variation:
// Variation - 1
//--------------
MyClass operator+(MyClass rhsObj)
{
return MyClass(this->myInteger + rhsObj.myInteger, this->myDouble + rhsObj.myDouble);
}
takes an object of MyClass
as input, which means a copy of rhsObj
is passed into the +
remaining the original object rhsObj
unchanged. This override returns a newly created object of MyClass
.
The second variation:
// Variation - 2
//--------------
MyClass & operator+(MyClass & rhsObj)
{
rhsObj.myInteger = this->myInteger + rhsObj.myInteger;
rhsObj.myDouble = this->myDouble + rhsObj.myDouble;
return rhsObj;
}
takes a reference to rhsObj
as input and the rhsObj
is updated in the method.
The last variation
// Variation - 3
//--------------
MyClass & operator+(MyClass & rhsObj)
{
this->myInteger = this->myInteger + rhsObj.myInteger;
this->myDouble = this->myDouble + rhsObj.myDouble;
return *this;
}
also takes a reference to rhsObj
as parameter, but rhsObj
is not modified inside the method. Instead, the MyClass
object on which the +
is invoked updated.
Upvotes: 4
Reputation: 18492
I would think variation 1 would be best for mainly one reason: if you had just the statement lhs + rhs;
, would you expect/want lhs
or rhs
to be modified? I know that I probably wouldn't in most (all?) cases.
Therefore that rules out variations 2 and 3.
Upvotes: 0
Reputation: 1
Conceptually, you want to return a new pair, so in your case the first variant is perhaps better.
Or perhaps you want to return one of the argument, but then I find confusing the name of the operator. It could be better +=
for the third variant.
Upvotes: 2