In this lecture, we'll learn how to pass in objects for user-defined classes into our functions, and to use those objects within the functions. I've already written the code that we're using that we'll modify it a little bit over the course of this lecture. I have a function prototype for a role it function where I pass in a die and the function rolls the die. I also have what I'll call a helper function that just prints the die state for a die that gets passed it. Down here in my main function, I'm creating a D20. I will print the die state of the D20 before I call roll it. Then I'll call roll it, and I'll print the die state of this variable in the main function. After I've called roll it. Within roll it, I roll the die and then I print out what number I rolled on this die, the parameter. Finally, printing the state of the die is just printing out the sides and printing out the top side. Our focus will be on the roll it function here. Let's go ahead and run and see how this all works. Before I call the roll it function, I have 20 sides on my D20 and the top side is one. I rolled an 11 and after the call to roll it, the state of my D20 in the main function is 20 sides and the top side is one. What that tells us is the roll it function uses the pass by value mechanism. It's making a copy of the die and passing in the copy rather than passing in a reference to or the actual die itself. Now, you might be asking yourself, how can it make a copy of the die? I didn't write any code in the die class that says copy this die into a new die. Well, it turns out that by default, C++ gives us something called a copy constructor. A constructor that will copy an object into a new object and it just copies over the values of all the fields or members of that original object. That works fine here because our die just consists of a couple of ints for our fields. But, more complicated objects, particularly those that have pointers to other objects or strings or references to other objects. Those are more problematic using the default copy constructor. Because the default copy constructor does something called a shallow copy. I know we're going to talk about strings in the next lesson. But let's say we have a string of characters in the original object. When the default copy constructor copies that string over, it just copies over a reference to the same location in memory. If the original object changes one of those characters in the string, the new copied object also gets that change. That's called a shallow copy. There are cases where you're going to want to actually have a deep copy. Where when you're making the copy, you actually create a new string and copy the old string into the new string. There's a distinction between shallow copies and deep copies. The default copy constructor does a shallow copy. We don't care in this particular case, but you may find yourself with more complicated classes that you need to implement your own copy constructor instead of just using the default. But, here, the default copy constructor works fine, except that, that doesn't actually change our original die. We know how to fix this. We can make this parameter use the pass by reference mechanism instead. We'll need to change the function prototype as well. Now, when we run our code, you can see our original D20 is 20 and 1 we rolled on 11 again, oh well. Then after our call to the Num Side is 20 still, but our top side is 11. As usual, passing an object by reference makes it so that we can actually change the object inside that function. Let's do one more thing, let's actually say we don't want to change the die and roll it, which is silly, but I want to show you that if we put that const keyword, again, the compiler says no, you can't change the parameter because it's marked as const. It's not super-smart. The compiler is not super-smart because we know that roll does change the state of the die and we know that GetTopSide doesn't. It would be nice if we could get the top side that's not actually changing the die. But that's okay, we don't want this to be const anyway. But I wanted to show you that the const keyword works the same way for the objects of classes that we've defined. Let me get rid of that before I give you the code and back up at the top as well. We'll run the code one more time to make sure I didn't break anything and I didn't. Hey, we've got an 11 again. One more thing before we stop. With vectors, I talked about using move semantics rather than using the pass by reference mechanism. It is in fact the case that you can have your custom classes use move semantics as well. What you need to do is you need to write something called a move constructor. That's certainly possible and reasonable and something you may even need to explore as you continue building your C++ knowledge. But because we don't need move semantics for our custom classes in any of the lessons, in the courses in the specialization, I'm not going to cover that material, but you can explore that on your own if you ever need move semantics for the classes that you write. To recap in this lecture, you learned that the pass by value mechanism is still the default that C++ uses for objects of user-defined types as parameters. We learned that we can use pass by reference instead to modify the object inside the function. We also learned how to use the const keyword to keep that object from being changed within the function, even if it's passed by reference. None of this should come as a surprise because the C++ Containers are also objects. User-defined classes are treated exactly the same way as the C++ Containers are.