Hello again! In this video, we are going to look at addition operators. We briefly looked at the plus
operator before, and now we are going to go into a bit more detail.
So this is the prototype of the plus operator. It takes two objects of the same type, preferably
by reference to const, because that is the most efficient way to pass objects, and it returns and another object
of the same type by value. To invoke it, we just put "a plus b".
And that will be called as operator plus, with arguments a and then b. The return value is, or should be,
the sum of the two objects.
And that will be returned by value.
And this is defined as a non-member function.
And you might like to think about why that is.
The reason is that we have a binary operator. We may want to be able to perform a conversion.
If a or b is not type T, but some other type that can be converted to type T, then we want that
to work very naturally. As we did with the string class, with the C-style string.
And for that to work, it needs to be a non-member function.
There is also a plus equals operator.
So this will add its argument to the object, and then return the modified object.
This takes one argument of the appropriate type, and returns the modified object by reference. The
compiler will call this as operator plus equals on the object a, with argument b, and that will return
the modified version of a.
And that is defined as a member function.
And the reason for that is that we should write operators as member functions whenever we can.
Especially if, like this one, they modify the object.
So how do we implement these operators?
The obvious thing is to write a member function for plus equals, and a separate function outside the
class for the plus operator.
And you can do that.
But one of the key rules is "DRY", d-r-y. Do not Repeat Yourself!
These will basically do the same thing, so there is going to be duplicated code.
And we can actually avoid that. We can implement the plus operator in terms of the plus equals operator.
The way to do that is in our plus operator. So this is going to be outside the class, then we make
a copy of the first argument.
The one on the left. Then we call the plus equals operator on this copy.
Then we pass the second argument as the argument to the plus equals call.
And then we return this modified copy.
So the original argument is still unmodified. And that way, we only need to write the code once.
So this is an example of code re-use, which is always a good thing to do.
We only need to write the addition code once, in the plus equals member function.
And if we change our mind. If we add more data members or we decide that we want to do the addition
differently, then we only need to alter the plus equals member function. And we do not need to touch
the plus operator at all.
And now I m going to follow the well-trodden path of C++ instructors and implement a simple complex number class.
There is actually a complex number class now in the library.
I am going to call this one "Complex", with a capital 'C', so there is no confusion.
And this is going to be a very simple implementation.
Complex numbers have two parts.
So we have the real part, which "ordinary" numbers have. And then we have this imaginary part, which is,
if you like, a kind of extra dimension to the complex number. I am going to explain complex numbers in
detail when we look at the library complex number.
So if you do not understand complex numbers do not worry. You do not really need to know anything about them
for this video.
And then we have a constructor, which will create a complex object from two doubles.
So this is just going to override the default initial values of 0.0 for the members.
So we said we are going to define the plus equals operator as a memory function.
This needs to add the real and imaginary parts of the object separately, and then return the modified
object.
So it would look something like this.
We have our plus equals operator, which takes a Complex object by reference to const, and returns a Complex
object by reference.
Then we add the real part of the argument to our real part, and the imaginary part of the argument
to our imaginary part.
And then we return the modified object by reference.
So that is the actual details of the addition. And then, for the plus operator.
So this is going to be defined outside the class.
We take two Complex objects by reference to const.
We return a Complex object by value.
Then we make our copy of the left hand argument.
Then we call the plus equals operator on that argument.
So this is going to addd the members of the right hand argument, to the members of a copy of the left
hand side. And then we return that by value.
So that is going to be the modified version of the left hand argument.
The original is still unchanged,
of course.
So let's implement this.
So here is our Complex class, with the real and imaginary members and our constructor to initialize
them.
Here is our plus equals member function, just like it was on the slide. And I have also added a print
function to display the values of the members.
And then outside the class, we have the operator plus. Again, the same as on the slide.
So we are just delegating to the plus equals function. So that can access the private data of the
class.
In the main function, we create some objects. And we try out our member functions and operators.
So let's see what we get.
So we have two objects with real part 1 and imaginary part 2. Real part 3 and imaginary part 4.
If we add them together, we get 4 for the real part and 6 for the imaginary.
And then with the plus equals operator, after doing that, c1 has the real part 4 and the imaginary
part 6.
So that all works correctly.
So what happens if we want a type conversion?
So let's add some code to do that.
Let's create a new object.
And then, let's say, we want to have 1 plus c2.
So 1 is actually a special case of a complex number.
It's a complex number where the imaginary part is 0.
So we should be able to convert this.
But before we can do that, we need a constructor which takes a single argument.
So let's add that...
So this will just set the imaginary part to 0.0, because it's a real number and not a complex number.
In fact, we do not need that, because the imaginary part has a default value of 0.
So we can just remove that code.
So again, another good use for in-place initializers, making the code a bit simpler.
So we have this constructor now, which can convert a double, or an int coerced to double, into a complex
number.
And then this will call the non-member plus operator, and the compiler will convert the 1 into a Complex
object.
We hope so, anyway!
And there we are.
So our object c4, which is 1 plus c2.
So it is, 3 plus 1 makes 4, and 4 plus 0 makes 4.
Yep.
So that all works.
Okay.
So that's it for this video.
I'll see you next time.
Until then, keep coding!