Hello, everyone and welcome back.
In this video, we'll go over the challenge solution 2.
This is the solution for the overloaded operators using non-member functions.
So I'm in the section 14 workspace in the challenge-solution2 project.
And you can see my header file now from the private modifier
down, it's exactly the same.
The only thing that's changed is that I've declared prototypes for
my overloaded operator functions, and they are all friend functions.
Now we don't have to do that.
We can certainly not have friend functions and work through
getters and setters and so forth.
But for the purposes of this video, I'm making everything a friend.
So I've got access to everything that's private in this class,
which is really just that string pointer right here.
Now as you can see, when we have something like operator
minus in this case, we're overloading the unary operator.
There's exactly one item in the parameter list.
And when we have something that's binary, we've got two
parameters in the parameter list.
So it's a little bit different from using member methods.
And that's about it.
Now what we do is we basically have to implement these functions,
and you'll see they're very, very straightforward, same
idea as with the member method.
So let's go to the implementation file here,
and we'll start with the equality operator.
Now we don't have -- remember, in all of these cases, we no
longer have a this pointer.
There's no object dot operator method because they're non-member functions.
So we don't have that this pointer.
But we do have another object.
And in this case, we have left-hand side and right-hand side.
And all we want to do is compare the left-hand side string with
the right-hand side string.
And you can see that we're doing that right here in
the string compare function.
We're comparing left-hand side string to the right-hand side string.
And if we get back to 0, they're the same, and that's what we're returning.
So we're returning true false here.
Same exact idea.
The not equal operator is exactly the same thing except I'm negating
the result right here with the bang for the less than and
greater than overloaded operators.
You can see that the code is almost exactly like it was in the member
method version except that I don't have this on the left side, I've
got an LHS or left-hand side object.
Okay, so let's take a look at make lowercase.
In this case, this is a unary function.
So I've just got one argument right here.
And what I'm doing is same thing I did before.
I create an area in memory to copy that string into and what I'm going
to do is make it lowercase, and that's what I'm going to do here.
I've allocated enough space for that object strings length plus 1, then
I copy that object string character by character into buff, and then I
simply loop through buff and make each character is lowercase equivalent.
When I'm done with that, I construct an object that I'm going to
return right here, and I construct it based on buff, return it.
And don't forget to delete the buffer as we always do,
so we don't leak memory.
The concatenation operator, same idea.
I've got the left-hand side and the right-hand side.
So obviously, you're going to have left-hand side plus right-hand side.
So we need to allocate another character buffer here.
That's the length of both those strings added together plus 1.
So you can see here we have left-hand string, here we
have right-hand string.
We copy the left-hand string over, and then we concatenate
the right-hand string onto that.
We create the new object here based on that new string that's concatenated
now, and we return it, and of course, we delete the buffer as well.
That's it. Really straightforward.
Now they get really really simple to implement because
we've got our plus equal, right our concatenate and a sine.
Well, we can implement that based on our concatenation because
plus equal simply means left-hand side equals left-hand side plus
right-hand side, so we can express that directly which leads to
very, very readable code here.
The repeat operator or the star operator that we're
overloading, same idea.
Remember, repeating something just means adding it over and over.
So we'll take advantage that we've already overloaded that concatenation
operator right here on line 44.
We're using it right there.
So given n, we're just simply going to loop that many times and say temp
equals temp plus left-hand side, do it again and again and again.
And we're just basically tacking on that string to
itself over and over and over.
When we're done, we return temp.
Our star equal operator or repeat and assign operator works the same.
In this case, it's a binary operator, it expects an object and then the
star and then an integer is how many times you're going to repeat it.
So we'll do the same thing.
We'll take advantage of the fact that we've already overloaded
the repeat operator or the star operator in this case.
We'll simply say left-hand side equals left-hand side star n.
That will call this.
It will take care of it.
And then we return left-hand side, so we can keep assigning.
And the last two that are left are the pre-increment and
post-increment operators, which just make the strings uppercase.
So the semantics for the pre-increment is simply just increment that
string, it's really straightforward.
The string belongs to obj, right.
Remember, this is a unary operator, so we only have one object here.
And obj has an str pointer that points to a character array on the heap.
So what we're doing is just looping through that character array one
item at a time, one character at a time, and we're setting the
item of that object string to the uppercase equivalent of it.
And then we just simply return the object when we're done.
So you can see we're actually modifying obj here, which
is exactly what you would expect with a pre-increment.
So the post-increment is very similar.
We need to keep a copy of the original object, so
we're doing that right here.
We're creating a copy temp based on object, which is the
one that's being incremented.
Then I'm doing a pre-increment of object, which takes care of making
all the characters uppercase.
And then I'm returning the old object.
So you can see that this line right here actually
modifies the current object.
And this line right here returns a copy of the original object,
which is the exactly what the semantics are of post increment.
I wrote a comment here, as I mentioned before.
Make sure you call pre-increment and not post-increment.
If you call post-increment, this method here will be called over
and over recursively and you'll never be able to break out of it.
So that's it.
If we run this, we should have exactly the same output as we had before.
Let's try it,
enter a string to repeat.
And we'll do the same string I entered before dash three zeros and a dash.
And I believe I said five last time, I'll do that again.
And there we go.
We've got our five 0 0 0 strings.
We've got 60 of these now, and the rest of the code is
exactly the same as it was.
All right, so congratulations.
I hope you did well on this challenge.
You can say now that you're no longer c++ beginner programmers.
That's for sure.
Yeah, you've learned a lot about the way c++ works behind the
scenes, operator overloading, the constructors, the move assignments,
the regular copy assignments.
So you've learned a lot.
The next step is to learn about inheritance and polymorphic functions,
and that's where we're going to go.
And I should mention one last thing is when you look at these
test cases that I created, these aren't really test cases.
They're just little pieces of code that exercise some of
those methods that we wrote in functions that we wrote.
When you do testing, you really want to do proper testing using
unit testing, using some frameworks such as you know unit test plus
plus or something like that.
So keep that in mind, we're doing this just to keep it simple and
not have to learn other frameworks in order to learn this framework.
So I'll see you in the inheritance section.