So let's turn to C++ and see how much better we can create the new type point. First off, we're gonna choose the new key word class. Now, we have point. We're no longer gonna need that old trick, the old hack in C with type def. Point, the class name is automatically the type name. The next thing you see that's different is there's an access keyword. That access keyword can be one of three keywords. The three keywords are listed here. Public, private, protected. For the moment, we're gonna leave out protected. It's part of what we call the inheritance scheme. We're gonna leave inheritance for another day. Public and private are what you really need to know for most of your programming. Again, this is one of those wonderful things what I called 90% rules of programming. If you learn a few simple ideas, they work for 90% of what you need. So you should really concentrate on learning the basics, cuz that's widely applicable and then the addition 10% you can learn as necessary. Public and that's where protected comes later on. Public just says, everybody should visibly see what I'm declaring. So if I say public double x, y, it means everybody in the world gets to look at double x, y. Private is just the opposite. Private says, restrict the access to things that have this class as its scope. Keep it just very limited. What I like to do is say, private is part of what I'd called the black box principle Hidden away in here is the private stuff. Now notice if you buy an Apple and you try and open it up, let's say, you buy an Apple iPhone, the warranty goes away. You try and open that and mess with it, the warranty goes away. It's a black box. The manufacturer only wants their authorized specialists to work with that black box. So what you get to see is a few controls on the surface, that's the functionality of the iPhone. You really care what operating system and what processor is running the iPhone. Most 99% of the world do not have a clue as to what the processor, internal to the iPhone is or even if there is a processor. They just know it as oh, I have it as a phone or I have it as a mapping device or I have it as telling me rotten tomatoes, movie reviews. So they know it as here are some apps. Here's some phone function. Here's some camera function. How that all works internally, that's a mystery. Apple doesn't want you to mess with that, so that keeps it a lot simpler. So again, that's a really important principle in building things. Hide away as much as possible that the non-expert, the ordinary user doesn't need to know and just give them the public controls, the little knobs or whatever are on the face of the device. So here is class point and class point is where we're trying to create a new user defined object and some of what we want to understand is how to use the OO technology, the object-orient technology. What are some of its key elements? The overriding principle in the object-orient technology is to make your new data object seem natural, seem compatible with the existing programming language data type such as int or float. Among the principles, we try to follow are data hiding. So private Is where we hide representation. In order for this not to impact efficiency, remember when a member function or an OO speak on member function is sometimes called a method. Is automatically in line. So, it's automatically, highly efficient. And so this return of x really is just not involving a function call, it just really gets the internal value of the variable x associated with that instance of point. And then the set x, which is also called a mutator method, because it can change the value of the hidden representation is also efficient. It's really just at that place in the code where you're gonna call that member function zed x, you just replace it by the simple assignment. Data object .x equals data object .v or the v-value, I should say that's being called. So again, if you want to review object orientation, you're supposed to have a background orientation coming into the class, but you can use something like the Wikipedia to review this information. And if you follow this template, namely use public for the kinds of behaviors you want your object to have, use private for representation. And then as we will see, you make this as rich and natural a set of class functions that gives you an easy time in using point in your normal programming. So here, we continue with the object-oriented paradigm and what we need to do and some of the things that C++ lets us do and C++ is the most powerful object-oriented language. It's actually multi language, but it allows, for example, operator overloading which many other object-oriented languages, even C-based ones don't allow. And again, that gives us the opportunity to extend the semantics of even operators over to our new objects, so that there's A fairly natural understanding of how those new data types will interact with the old data types. There's an expectation that we will keep the interface. So, here we have something called a point. A point as you remember from high school math is a mathematical object. And if you're doing some analytic geometry you can add two points to turn them into a third point. And the way you add them in the x, y plane is to take their x and y values and combine them. Well, that's a natural operation. It's the operation binary plus. I have to say binary plus because C++ also allows for unary plus. Unary plus is normally a no op. But binary plus which on, natural built in native data types like int, we all know you add three plus four you get seven. You add 1.2 and 2.2 and you get 3.3 in the float or double domain. So plus is a natural operation. You should only be overloading it, idiomatically, you only want to overload operations where there is an existing semantic. Which generally means they must be mathematical objects. You don't wanna overload your general widget where somebody doesn't understand what a plus for two widgets are. I mean, what if you take a Swatch watch and add it to an Apple iWatch. What does that mean? It's hard to conceive of. So you wouldn't want to be using overloading of operators in non algebraic, non mathematical domains. But here, plus has a perfectly good sense to it and indeed, if I was somebody who was going to be dealing with points constantly in my programming I would want the ability to use the arithmetic and mathematical notations, including those operators. So we see what the semantics are, and they are exactly what you can imagine from your high school math. Now, we also want to overload the output operator. And this is very important. So, study this because this a critical idiom. Any time you have a new data type that you've created, a new object that you've created, you generally want to overload this. Again, it's an expectation, it's a community expectation. So if you're the designer of this new object and you're gonna give it to other people on your team, they're gonna to expect the IO to work on it. You have to give that IO semantics. And here's the semantics. We print a paran, we print out the x value of the point, we print the comma, we print out the y value, we print out a closing paran. So exercising this on some point we might see on this screen three coma four. And that would be the point with the x-coordinate three and four in the x, y plane. Now, critical to this is to look at the function signature. So the return type is an ostream. So that means you're taking, and the operator overloading is a binary operator and it's a binary bitshift operator. So even though it's natural for us in C++, always think of this as an IO operation. It is an intrinsically. Intrinsically if we have two data types, like two ints, we're forced to use it as a bit shift operator. However, where we have an ostream as a first argument, as here we do. And in this case we have the object as a second argument. Then this function signature makes us select this version. Don't forget, this is a form of operator overloading. And the signature matching algorithm that the compiler uses says, do I have an available definition for this? If I don't have an available definition and I attempt to do something like this, I'm gonna get a compiler error. If I have an appropriate available definition which is use it on a stream, an ostream and then apply it to a point then this is the behavior that we're gonna see. Now critical is that the ostreams are both passed in by reference and the return value is in ostream by reference. Why? Because suppresses any kind of copying. So that's efficient. And we wanna return this operator because we want an typical IO to use this multiply, you see it here. It's really a binary operation. And the binary operation goes something like this, out is the stream and then you print the action is to print left paran. And the result is really that you get this again as out. So you get the same ostream as out, but you've had this print behavior. So you're gonna print first this, then you're gonna get an ostream, then you're gonna print three, then you're gonna get an ostream, then you're gonna print comma, and so on. So those semantics are call by reference. But look at this. This doesn't have to be written this way, but it's expected to be written this way. Sometimes for simple types, this could be call by value. You would see the same behavior. However, it's just useful to call your data object, because your data object, your newly created object, might be something very complicated and again you want it officially passed and you know it's not going to be mutated. So the const shows that it's not mutated. And passing by reference suppresses call by value semantics so it doesn't get copied locally which could be an expensive operation. And then you just print the underlying value. Again, this is a very important idiom to understand. It's most useful. Once you understand it you can apply it to any of your own programming any time you create a new class. You want to be able to design a program like that and remember You return out because of the binary operator. You want to reuse it in a stream like this, a stream of operations like this. Now, it's use in main, just to test this, and again If you're working at home, you should try this out. You should add operators. You should think about it,. You should run your own version of it. You should extend it. That's the only way you're going to really get to make use of this. We declared a point, {3.5, 2.5}. We declared another point, {2.5, 4.5}. We output those two points. So what's this going to look like on the screen? Well, hopefully, if I have what I did before right, we're going to see 3.5, 2.5, all in parenthesis, with this comma there. And then we're going to have have a =, that's this expression. And then we're gonna have b =. And then, the same thing. We're gonna see (2.5, 4.5). That's what's gonna hopefully show up on the screen and then we'll have the new line. And then if we do the sum, the sum is going to, in effect, deal with all these operations properly. You could have parenthesized that, but because of operator precedence, this will take precedence and occur before the left shift operator. So + has higher precedence than shift. And you will get a + b. a + b is going to end up with (6.0, 7.0). And that will be sum. Hopefully that will be your result. You should try that at home. So, what have we learned? User defined types. Using point in main() looks very much like a native type. It looks like we used double. It looks like we used int. It looks like we used char. This is your key goal in object orientation. To be a good object oriented programmer, when you've created a type and when somebody understands the intuitive semantics of that type, the type should readily look like an ordinary C type, an ordinary C native type. And we accomplish this by having point have properly overloaded semantics that gives them an appropriate look and feel like a native type. Now, when we stick methods in the class, those methods are frequently going to be accessor methods. And sometimes they're going to be what are called mutator methods As a senior professor, I'm allowed one or two errors a lecture. So that shouldn't have been val. That should've been v, or alternatively, it should have been val over here. This is what we call a mutator method. Method. Because it changes the underlying value of what a point is. And this is purely an accessor method because it gets us the value. And class members, this is the critical thing, when we're building a class we have access to everything. We have access to private, we have access to public. Everybody has access to public, but we have access to private or, when we go over to inheritance, we'll also have access to protected as well. The way we get access is through this dot notation. p1 will have its two doubles, x and y, defined. So p1 dot x and dot y are available to getx. That's why, when p1 activates getx(), when this method getx() is activated by the object p1, it returns the hidden value for that particular object instance. So what lessons do we wanna take when we go to build an object? Object construction is needed for OO. Built-in objects such as the native objects double, fixed arrays, they're all built by the compiler. But a big part of C++ mastery is to get the skills so that you can write the code, you can write the class, you can write the class methods, the member functions that have you build the object. Crucial to building the object is a very special method. That method is given a special name, it's called a constructor. Rather intuitive, constructor, construction. So when you want to build an object, you need something that builds it. The compiler knows how to build native objects. But the compiler needs instructions. And what you intend to do when you're building these new objects, the objects, the domains, the widgets, that you are going to use, you're extending the languages into new areas. So, here's point. The key idea is That only constructors have, as their names, the same names as the class name. All the other methods have to have different names, like getX and setX. But when you see inside a class what looks to be a function and its name is the class name, then you automatically know it to be a constructor. And the constructor also has the ability to take different argument lists. And there are several special types of constructors and we'll go into that in a second. But the standard special constructor is called the default constructor. And it's the default constructor cuz it's how to build the object when you give it no arguments. So here is a constructor where you give it no arguments. And when you build it, you say, oh, a point in which I give it no arguments, well that's just gonna be the point that's in the x y plane, at the intersection of the two axes, that's gonna be the special point, 0, 0. And that's intuitive. That might be what would be expected. Normally when you have native types and you leave them uninitialized, the compiler frequently initializes them for you to zeros. This is a sense of using some standard null value for the initialization. But here you have to give proper semantics, otherwise x and y, the secret parts of the instance, the secret data members for the instance, wouldn't necessarily have an initialization. Now, I'm showing you how to do this, the semantics, in two different ways at the moment. The second way involves a special keyword, this. This is what we call the self reverential pointer. One of the things that's always something that's wonderfully confusing in mathematical logic, or indeed in computer science. Is where we get self referrentiality, famous, logical puzzles about villages, in which every man is bearded. And only the barbers allow to shave mens beards, and the barbers beard. And you have to ask the question, who shaves the barber? So is that an illogical or impossible situation. Anytime you get self reference- wonderful series I've been watching forever is the British science fiction series Doctor Who. And Doctor Who has a pun, plays on the whole question of self-referentiality. Doctor Who. And indeed, in Doctor Who, he's a timelord and he's floating around in the cosmos. And he frequently comes upon himself in certain special episodes. So you get all sorts of paradoxical self-referential situations. So again, self-referentiality, that's difficult. In order for a member function method to access it's own members, it needs some special mechanism. So either x and y are known to be inside that class or they can be pointed at self-referentially through this special this pointer, that always exists for any object created. And we'll make use of it, and we'll see why it's important. Okay. That was a taste of constructors, there's also an analogous special method, called a destructor for destroying an object. So anytime we wanna be able to create things, we wanna be able to destroy them, we wanna be able to return resources to the operating system. It's very important to keep our environment clean, manage our environment carefully. It's a major topic for those of you following in the text, it's very important to read Chapter 5. And I will continue next time with this material.