Okay. So, we're going to discuss a really important topic. Which is the topic of how to effectively copy things. And, the two major forms of copying that we find in computation or what are called, deep versus referential, or shallow. Deep, well, we have a slide here. It's just pi a transcendental (number). That's in effect, a deep notion. In fact, it goes on forever, without any pattern or just an easily discernible pattern. Mathematicians, now for centuries, have looked for a way to study and understand the patterns behind pi. So it's a relatively deep notion, compared to what I might call, shallow. You know, mom just throws in a lot of apples, makes a very tasty pie. Shallow can be good, too, so I'm not trying to say that deep is better than shallow. There are different things going on. Now, think about the days that you were actually using the library, as a library with physical books. The Library kept the Encyclopedia Britannica, in the Library and then allowed users to come in and use that Library. Why, well it's very expensive to reproduce the Encyclopedia Britannica, so since it's a super expensive resource, they kept one resource and allowed people to go and use, it in a way that they couldn't mutilate it, damage it, they tried to, you know, keep it pristine. And many people could use it, after all there are a whole bunch of volumes. you could however many volumes have that many simultaneous users, you could have. Because they'd be affecting different parts or reading different parts of that one copy. On the other hand, if I have enough money or resources, and I needed let's say the article on Alan Turing in an encyclopedia Britannica entry, I might go in, and make a deep copy. By deep copy, I mean I might xerox it, I might reproduce that copy. Now, I have my own copy and so, with my own copy I can underline it, make notations, without affecting the original copy, which had to be kept pristine. So with a deep copy, we have something expensive, where we in effect, manufacture a second version. With a shallow copy, we have multiple users who if you want,( remember in the list example we had cursors.) everybody could have a cursor into the Encyclopedia Britannica. Use it at different points because none of them are going to be making changes. So, deep copy, shallow copy; questions are questions of utilization, cost and modification. Now, in the remaining part of today's lecture, we're going to talk about deep copies. So, the deep copy is the safest, I can turn over a new copy. I can manufacture yet another digital version, of what you need. And you can go off and use it in whatever way, shape, or form to your heart's content, because your use of it, even if you modify it, isn't going to affect my use of it. So that's the high level view. Now when we're doing copies, what we want to look at, is the copy constructor. So it's going to be the copy constructor that in effect, will determine whether we have a shallow or referential copy. So, on the notion of a referential copy, if you think of a list and I have, I, let's say I produce a big list. Maybe it has 10's of 1000's of list elements and I want to now use it, in two different, two different ways. Well, as long as you're not going to modify it, I could make the shallow copy, by creating yet another pointer to that list, and navigating the list with two separate cursors, or pointers. And yet both copies, the pseudo copy, the copy where we have a further pointer to it. it's very cheap to do. Really, the referential copy is just the, the need there, is just a single pointer, which is a single variable, typically four bytes and an address value. However, if I'm going to require that several people use it, and they may be modifying the copy, I'm going to have to take the 10's of 1000's of elements and reproduce them. And then the copy constructor's going to have to be something that goes to the heap and remember that idiom, where we marched along with that while-loop and the print. So earlier, we looked at the print() method, so you could go back to it and you would see, well I'd march along and for each element in the new list, I would create an element, for each element required in the new list, I would go back and copy the element in the old list. So here's such a copy constructor. again, here's the simple case where everything is just null. So it's really easy to copy a null list. It's very simple. And again you can see, the copying is going to be proportional to the size of the list. And once again, I'll just remind you that if you have a C++11 compiler also, null pointers are an appropriate initialization. And here is the equivalent of, this could also be done with a while (loop). So we have a cursor, a list head, while the cursor is not equal to zero, we chain and create. So we're going to need something with a "new" here (at this point in the code). I'm going to let you write in the code for it and that's going to be again, deep copy. Because for whatever this list is, the existing list, the existing header, the new list, head 2, is just going to march along. There's going to be a cursor here, it's going to copy each element in turn, march along until its done. Here's the internal code. We create the new list element we do a link, we keep moving and that inner loop will let us create the entire list. Though again, this just fills out the code, for the copy constructor. You can follow along and you should test it, make sure you understand it and you could do it in other ways as well. With while-loops, you could practice to do it with a while-loop. You could practice to do it with a recursive format.