The course is part of this learning path
In this course, we will build on your existing foundational and object-oriented oriented skills and enhance them by looking at templates, the Standard Template Library, and other skills to help you in your builds.
- Learn about function templates and class templates
- Learn how to write efficient and excellent code with the data structures and algorithms in the standard template library
- Learn about smart pointers to manage dynamic memory automatically
- Understand friend functions, friend classes, and operator overloading
- Beginner coders, new to C++
- Developers looking to upskill by adding C++ to their CV
- College students and anyone studying C++
To get the most out of this course, you should have a basic understanding of the fundamentals of C++.
In the last lecture, we discussed how classes and functions that are not members of a given class could be granted special access to the classes private and protected members using the syntax of friend functions and friend classes. In this lecture, we will discuss the topic of Operator Overloading. We can define the behavior of an operator for different data types, much like we do for functions. In fact, the syntax is very similar to function syntax. Let's create a new project called OverloadingFun. So, create a new project, Empty Project, OverloadingFun. And for this one, again, we're going to copy our good buddy, the Rectangle class, not the version with the friends in it this time, but we'll copy the original into our OverloadingFun projects. So, DynamicRectangles, we'll go in there and I will grab the Rectangle.cpp and Rectangle.h and we will copy those and put them in OverloadingFun. Now, let's find it. There it is. And we will paste it there. Looks good to me. Now, we will import them into the solution. So, add existing item and we have Rectangle.h and Rectangle.cpp and OverloadingFun project. I will add those and then drag the Rectangle.cpp into source files and now, I will create a main.cpp. So, main.cpp. So, let's do this. Rectangle.h.
using namespace std; int main(), return 0;. Now, over into Rectangle.h. We go and we need to add a little bit to this. I'm going to separate them with some space but it really doesn't matter. I will have this syntax. The operator is actually a keyword so you have a boolean returning ==, and I'll explain the parameter in just a moment. So, if we look at this, we see that the operator keyword is associated with whatever follows it immediately, the operator that you're overloading and you notice that it takes a parameter. Now you might think, well, wait a minute. This is a binary operator, which is true. It has a left and a right operand. Well, the left is whatever this points to or whatever is the data referred to by this. So, whatever Rectangle is on the left hand side is going to apply its own data and members when you define this function. The one on the right will be passed in as a parameter. So, it's pretty cool. Now, we have a Rectangle returning operator+ that also takes another Rectangle which is a constant. And then you have void operator = (a const Rectangle other);. Now, you'll notice that even though we're not modifying the other constant, there are other Rectangle rather so, we make those const. This one does not have const at the end and its void.
So, it doesn't actually return anything. In this case, we didn't define it to do so. What we're defining it to do is to set ourselves whatever Rectangle we're in equal to stuff that is in this Rectangle will define that behavior. So, since we're changing our own data, we need to not make it a const. These two on the other hand, the + will take our data and other's data and it will do some sort of combination and then return a new Rectangle, but that doesn't modify either Rectangle so we can make both of them constant. So, this one is constant and then this method agrees not to modify it. Same thing with this one. This one returns a boolean. We compare ourselves to other and we do not make any modifications to the internal data. So, this one can be const, a const method as well. Now, let's take these and we're going to go over to Rectangle.cpp and we can go to the bottom and here are the operators. And again, it does not matter. That comment's just for our benefit. We will delete, give them bodies just like any function that's a member. The same thing goes here. We have to put the name of the class in the scope resolution operator. These are actually called Operator Functions, as mentioned. So, operator equals, this one is pretty easy. We can put if statements if we wanted to or use variables but this is pretty simple. I'm going to return, give my length.
This could also be this arrow length if you wanted to do that. So, if my length's equal to the other Rectangle's length and my width is equal to the other's width, that will return, this whole thing will be true if both of these are true. So, that means this == will return true. Now, you could decide you want to define it based on perimeter or area or some other features. That's totally fine too. But we're defining it based on length's equal and width's equal. So, however you define it, when it returns true, that means they are equal according to our definition. This one is pretty simple. We create a new rectangle. We call it newRect and then the arguments are the length, width. So, it's my (length + the other.length). So, that would be the total length of this new Rectangle. And then we'll have the other, width + the other.width); and then we return newRect;. So, length and width. We just create this new Rectangle and then return it and that's what we expect. So, what about equals? Equals again is not const because we're modifying our own data as the Rectangle upon which it's called, in other words, the left hand side of the operator. So, what do we do? When we set our length = other.length; is or whatever the other guy's length is, our width = other.width;. I keep saying other guy. It's the other Rectangle.
And we of course, want to do some tests in main. So, over in main.cpp, I can create a few rectangles here. So, we'll say Rectangle rect1(10, 20);, Rectangle rect2(50, 100), rect3(10, 20) also, and then Rectangle resultRect;. We'll keep that so that we can set it equal to something. So, we'll say resultRect =. Now, this will both test the assignment operator and the addition operator. See? If you had not overloaded these operators, you wouldn't be able to add rectangles. Like what does that mean to add rectangles? They're not simple. They're not little integers or doubles or something simple. So, you have to tell the environment what do I mean by adding rectangles? So, we'll also do a couple other tests here. So, I could say is "rect1 = rect3?". And then, here's my little friend <<boolalpha and then actually print out the result true or false of rect1 = rect3. And I can also do this, "resultRectangle area:. So, I could say resultRect.area(). You could also, I guess before that you could say resultRectangle length * width:, and then I'm just going to say resultRect.getLength(). And then, maybe put a little * in the center so it'll look pretty, getWidth(). And we'll do that. I'm going to actually bring that down just to keep it cleaner. And let's run this to test out the addition assignment and equality operators in our Rectangle objects.
So, debug. Start with the debugging. And we missed a space there but is rectangle one equal to rectangle three? Well, by our definition, they are. They each have the same length and same width, so that's true. The multiplication here, we have the 60 times 120 which is 7200. Where did the 60 and the 120 come from? Well, it added rect1 and rect2, so that's 50 plus 10 is 60 and then 100 plus 20 is 120. So, that's why their lengths and widths correspond to the 60 and the 120. So, we have defined what it means to add Rectangle objects, assign a Rectangle to another Rectangle, even the result of an addition that is a Rectangle itself. And also, we've explored how to overload the equality operator. Many languages like Java don't allow operator overloading, instead use methods to compare objects like compareto() and equals and other methods but C++ gives us this ability. So, knowing how to utilize this feature is very useful. Since you've had a glimpse of how we overload operators, I've got a great little challenge for you. I'd like you to add the not equal to or is not equal to operator to the Rectangle class in the current project and test it out in main. Should be simple. So, pause the video and give this your best shot. Come back when you're done or if you need some help. How did that go for you? Were you able to overload the != operator?
Let's do it together. So, inside of Rectangle.h, I'm going to just add this. I'll group it with the equality or equal to operator. So, right here we'll put operator!= (const Rectangle& other). And again, it doesn't make any changes, so we can put const. I will grab this guy right here and I will go over to Rectangle.cpp and again, group it, keep it in the same order. It doesn't really matter but I try to be a little bit neat. And of course, we have the Rectangle and the scope resolution operator. Now, how do we define this? There's a couple ways to actually do this. One would involve actually saying not and then putting the data in this equal to other's data. And then, it would actually be able to use this operator. So, that would be a sneaky way to do it. But if we want to fill it up with code directly, we can do this. We can say (length != other.length). If that's the case or width, actually we don't need those, or width != other.width. If either of those is the case, then that's what we expect. We would say that this is not equal to the other Rectangle. So, if my length doesn't match or my width doesn't match, all I need is one of them to not match and that's enough to say that they are not equal. AllNow, inside of main, we need to do a little bit of a test. So, let's go down here at the very bottom. Actually, you know what? Since we did the = right here, I'm going to put a couple <<endl here and right underneath here, I'm going to say is rect1 != rect2, << boolalpha<< (rect1!= rect2), and see if this works. So, let's run our app. Debug, start without debugging. And indeed, it says it's true that they are not equal. We could clean it up a little bit to make sure that there's an extra space here. Run it again, just make it pretty. And there we go. So, is rect1 = rect3? That's true because their length and widths are the same. Is rect1 = rect2? That is not equal to rect2. That's true that they are not equal. So, these should give the opposite. If I were to say is rect1 != rect3, that should be false. Nice work everyone. In the next lecture, we will do our first project for this section, making a Dictionary Class. I will see you there.
John has a Ph.D. in Computer Science and is a professional software engineer and consultant, as well as a computer science university professor and department chair.