 So my name is Chris my username on social media is program max The way this talk works is kind of more comfortable if you feel free to ask questions So you don't have to wait till the end if you have a question on a particular slide Just go ahead and raise your hand or sing and dance. Whatever you want to do Okay, so let's get started So this is the roadmap. I want to talk to or talk about today. I Doubt will have time to cover everything But that's actually okay because those last two points raw pointers and templates You don't super need to know them right now and I go into like really ugly details about them Just to try to make them less scary But you know if we don't get to those slides is no big deal Just be aware that what I'm going to show you in those slides You probably don't want to write in your day-to-day work So, you know if you go back later and look at the slides don't use that as an example All right, so let's start with free functions So I'm going to pick on Java a little bit and that's not because Java is bad it's just easiest for everybody to read and I want to use Java as examples that are clear, you know Whether you're coming from Python or Java or JavaScript whatever so here's Two cases of pure object orientation that happened in Java that don't really make a lot of sense So the first one is your entry points the static void main That doesn't actually have to be part of a class, which is why it's static in the first place Here it's related to class hello world app, but it could have been in any class So that really proves that it's not actually connected to a class at all and further We never had a chance to create a new instance of this class So it couldn't have possibly been related to the class like there's no way at all So that was just we had to do it because Java is pure object oriented Same with this the max function to get two integers Yeah, that doesn't have to be a class at all You know you pass in two integers it returns the max of the two this has nothing to do with the class So really here the class is just a namespace So this is an example of where pure object orientation isn't really perfect for all situations And if we translate those exact same things into C++ we wouldn't have done object orientation We would have just made them free functions so that they're free here means not like free as in speech or Free as in it's no cost to performance. It just means it's not related to class Okay, include and linkage so Java Python you're kind of used to these import things and the idea is some other file has it Let's go fetch it from that other file It's the same concept in C++. You'll notice I kind of did pairs here So the top one is sort of like getting a system library sort of thing And the bottom one is here is some of our code and then C++ You typically do those a little differently if it's like a library. You're probably going to be using those Angles and if it's your own thing you'll probably be using quotes This is roughly how C++ is built So I'll have two code files a dot CPP and B dot CPP each of them are individually set to or sent to an instance of a compiler and Compiler completely independent of each other So each of these is called a translation unit and then the result of that compile is an object file All the object files are then gathered up together and sent to the linker the linker combines them and makes the program for you So that kind of results in there being a compile phase and a link phase And I'm saying kind of here because the lines get a little bit blurred There are times when you do link time Optimization where it'll actually the compiler passes extra info over to the linker and then the linker can start rearranging functions How it wants But this is roughly how you'd want to think about it So by default because we had sort of separate translation units, and they don't know anything about each other by default there's no way for the Functions or classes or whatever in your files to actually interact and we probably want to interact with them We'll get to that in a second But remember the linker is going to combine all these things and maybe some of the functions I'm writing. I don't want to expose to the other Translation units when they get combined. Maybe this one was supposed to stay just within this file so there's two ways of Hiding it from other translation units one is to put your function in an anonymous namespace like this and The other is just to put static in the front static is kind of the old way. We prefer the Anonymous namespace in Chrome So I mentioned that if you have two separate code files You probably want to you know use functions from the other one or the class from the other one So the way that works is you'll have for example compute harmony dot CPP You pair it with compute harmony dot H. That's the header file for the actual translation unit And in the header file you're going to be doing forward declares of what you want to expose So for example, if I have some function compute harmony I'll say in the dot H file. Hey, I promise there's a function called compute harmony And you just have to trust me on it and at link time The linker will know where the function is and it'll finish the call But in your code if you try to call this function You can just trust me that the function will exist eventually at link phase so So here's what that would look like We have our dot H file all it does is forward declare there will be a function. This is what the signature looks like And we have the CPP file it includes the dot H file just to make sure the forward declare and the actual function link up And then that's where you put the actual function body and then in the other CPP file you also include that same dot H file So when we're compiling it doesn't know what functions going to call It just knows what the function should look like But at link time it'll know what the actual function is going to be any questions so far Great. Okay. So back to our little picture. This is kind of what it'll look like now We used to have a dot CPP and B dot CPP. Well now we're going to pair a and a dot H Sorry not compare Combine whatever Okay, so then we mentioned There's the two ways of including there's with quotes if it's our own file and then there's the angles if it's like a system file That happens at a pre-processor step before the actual like meat of C++ happens So what this ends up doing is effectively copying and pasting So it'll go open that file copy the whole contents of the file and then paste it on the line That was including it It's not 100% true, but that's like 99% true Okay, so we're going to run into a little problem with this copy paste thing And I need to set up a scenario to show you what this problem is going to be So previously we were just doing a forward declare of a function You're allowed to forward declare the same function 20 times if you want that's okay But a define is different from a declaration a define is saying this is the actual thing and you can't redefine something So if I have my header file and I put this class music type in it This is now a definition of that class. It's not just a declaration that there will be a class So now I have jazz dot H and it includes music type dot H And I also have classical that H and it also includes music type dot H And then I have play music dot CPP if that includes both jazz and classical We kind of created a diamond where we've included this music type dot H twice in this file And then that means this class has been defined twice So the compiler will yell at us and say whoa, whoa, you're not allowed to redefine classes Even if they're the exact same, I don't know. They're the same yet. So it'll yell at us So we need some way to protect from this So what we do is oh actually Already described a lot. So what we do is this a forward excuse me What's it called? protects Inclusion guards, that's what it's called So if the file name is music type h you just do this if not defined music type h define music type h Which means the very first time it'll enter this but the second and third time it'll hit that Oh, wait, it has been defined. We don't want to do this whole thing in the second time So that's kind of the standard c++ thing you see this in all of the header files and it protects from that multiple inclusion Okay, destructors and scope So imagine we're in Java land and we have a class that represents some sort of resource like a network connection or database connection file something like that We don't have deterministic destruction in Java, which means If I am currently using this file and then I'm done with it and I get rid of my reference The reference is still in memory until garbage collection happens I don't know when garbage collection is going to happen. It might never happen And so I don't actually know when the destructor is going to get called So it may never actually release the resource So that's kind of a problem Java offers us this finalize Oh, and by the way, that's you know, I could have called dot close on it But what if I forget you would rather have this automatic protection that as soon as I'm done using it it automatically cleans it up So we could add this, you know finalize overload But that kind of runs into the same situation. I don't know when it's going to be finalized I don't know when the garbage collector collector is going to come So that's not really solving the problem C sharp added the using keyword and then Java 7 added automatic resource management And that gives you a way to say like within this range of code I'm going to use this resource and when I'm done. I want you to garbage collect just that resource So it kind of solves this problem Kind of but now we have a separate problem and it's actually kind of similar The responsibility is on me to use this using keyword and if I forget I've fallen back into the same issue It's the exact same as if I had forgotten to call dot close So we didn't really solve the problem here So that's where C++ destructors coming. These are deterministic So this is an example of a destructor You can put whatever code you want in there to clean up your resource and as soon as that object is Destroyed if it goes out of scope or anything like that this destructor is going to be called so for example if I have a function and then You know, that's my class that I have as soon as we hit the closing Bracket here or brace. This is going to call all the destructors for all the objects in that function And you can actually just insert these wherever you want to like force like local destruction So that way it gets cleaned up between the first part and the second part. So The idea here is anytime you want to represent a resource you now have the ability to do that You know, I gave examples network connection file GPU is the one I'm going to use because that is less likely to throw an exception and in Chrome code We don't use exceptions. So it kind of fits the slides better For this next topic our AI I So I just showed you that destruction lets us represent a resource deterministic destruction does if we construct an object While taking that resource now the entire object is an actual representation of that resource So our AII means resource acquisition is Initialization the idea being that if we have constructed this object. It is initialized. It's ready to go So this is old code that you may have seen. This is the opposite of our AII So we have a GPU instance and we call dot open to get this GPU and that dot open call may have failed And then we have to call well if it fails, you know, do some error handling this is the opposite of our AII because We tried to acquire the resource, but we failed it, you know, the initialization isn't Acquisition or acquiring So this is the opposite of what we want Better way would be to have like a function that always succeeds and it just returns an instance of our GPU class and Now we don't have to track. Did it fail? Did it not in this function? It will always succeed the class itself doesn't need to know if it could have failed and If we didn't have the option for it to always succeed like maybe it could have failed Let's not store it in the class. Let's use something like base optional Base optional will either be the class you wanted it to be or nothing And so that way our GPU class doesn't have to track. Did I fail to initialize? Okay passed by reference and value. This one's a little weird because a lot of other languages They try to with garbage collection all that they try to manage this for you. You don't really get a clear View of what is a reference and what isn't a reference So i'm going to continue picking on java. I love it, but you know, it's really good for examples We have this function add to dictionary and we pass in a word Makes sense, right? In if this was c++ that would be passed by value And what would happen is when we call this function It would make a copy of the word that you passed in And then inside our function. We'd be operating on that copy Not the original value Which means we can make changes and all that and remember I told you about Destructors are called when the scope is closed As soon as we leave that function our copy is destroyed That's how it would work if we had written it that way The alternative to that the exact same thing except we put a little ampersand after our type You know add to dictionary word ampersand That is saying i'm not actually taking a word. I'm taking a reference to a word So in this case if you call this function and you pass in some word We are getting the reference to the original thing and any changes we make will actually be reflected in the original object This is actually pretty close to how java works Um in java even though we would have typed the other thing behind the scenes. It's passing references around So when we want to use this, um Imagine our word class is really heavy. It's really expensive to make copies You don't want to make hundreds of copies as you make hundreds of function calls And so you might be passing references around um The opposite of that idea is if it's really cheap to copy The reference actually is an indirection. It says here's the location in memory Jump to that location in memory and then get the actual thing you wanted So that extra indirection that's not free So if it was cheap to copy like say an integer or something like that, you might as well have just copied Oh another thing I really want to point out just because it's a reference that does not make it memory safe This is not garbage collected. It's just a pointer. That's it Okay, so in the last slide, it was a word reference. I'm going to change that now. It's a const word reference What that means is The thing that I'm referencing I don't want to actually change because remember it had the option to alter the outside value We probably don't want that if we're just adding it to a dictionary So we can just throw the const keyword in there That's pretty typical of old style c plus plus and this actually started changing in c plus 11 I don't remember if these slides get to that or not Okay, so here are those three examples that I gave before And I want to give a general guideline of when to use which So the first one const reference if you don't plan to ever change it and if it's kind of heavy to copy go with that um A better way to say that is if you're just going to observe the value that's when you use it Uh, if you're doing a normal reference non const That is if you want to modify the thing that they are passing it. So if you want to say like Initialize all of these values or something Uh, and then the last one when you don't pass the conference at all is either it's really cheap to copy the object or In new style c plus plus if you're potentially taking ownership of that object So for example, if somebody says I'm totally done with this. I'm not going to use it anymore I'm handing it off to you. It's now your responsibility If I'm the function who's taking that thing handed off to me I'm potentially taking ownership and that's when I might do this Okay, the standard library. We're almost to our ugly section. We're getting there So most languages I've been picking on java java has a fantastic standard library. It gives you so much functionality. There's Sockets, there's everything In c plus plus we have almost nothing in the standard library. It is itty bitty And that's actually kind of c plus plus is Weak point and it's getting better, but you know, we're still decades behind So Traditionally the solution to this is we use separate libraries something else if we need to socket we go find a socket library The standard library is huge despite me just saying how tiny it is It's tiny compared to java, which is astronomical But despite it being huge, I only want to focus on three things for now because I don't have a ton of time So I wanted to talk about string vector and smart corners string. You're familiar with that You know, I would say std for standard string dog name equals phyto Vector is just a way to have some contiguous memory and it's kind of like Uh, I don't want to use the word list, but it's just an array It's closer to an array, but it can dynamically grow and shrink as needed So here I have a standard vector of integers and I just initialize it one two three four And then I could also kind of combine these I have a standard vector of strings So now I'm containing the names amy and trick So although I'm only showing you these three things There's another piece of the standard that is actually not widely used, but we should all be using it a lot more I think this is because If we took c++ class in college or something We were all asked write this function that's going to loop over this stuff and do these operations And so we got used to writing the thing that's actually already written. For example, there's a standard sort People don't use it for some reason. I don't know why same with standard copy if so you can pass in a delegate You're sorry a predicate and say Uh, if the value passes my predicate my test if I wanted to be like values less than 10 or something If it passes the predicate then copy otherwise don't So, you know, there's a whole bunch of things in the standard algorithms not just these standard containers But people don't use them often So I encourage you if you want to look like a really smart c++ programmer start using standard algorithms People will be impressed All right smart pointers So you've maybe heard about pointer question Yes, uh, there is a website cppreference.com It is fantastic. It goes over everything including like This function was added in c++ 11, but before it you had this other function instead Um, so that website contains everything about the language the Standard and it's broken down into chunks where you can sort of navigate to where you want Great question Okay show of hands who here has heard of pointers in c++ and heard like horror stories or like battle scars or something Everybody okay. I wasn't expecting it to be that much. Okay, so you get the idea. They're terrifying. Um So smart pointers aren't those those are raw pointers and we'll get the that section later Smart pointers are sort of like let's stop terrifying each other So in a garbage collected language, you're familiar with you know If I have a reference the thing stays alive and I can have multiple references And it's still going to be alive until the very last reference goes away Then the garbage collector has a chance to come and clean that up In c++ that would be a standard shared pointer And you get that from include memory so This represents like if the object lifetime should actually be managed by multiple things This is where I need to sort of tell you to be different from what you're used to If you're used to a garbage collected language, you don't worry about who owns the lifetime It's just whoever has a reference But in c++ you really want it to be like this object should only live between here and there And then it should have that deterministic destruction and so Uh a shared pointer a shared lifetime is actually a really uncommon situation Even though that's the default in garbage collected languages That's weird typically like my car has wheels. It's not like well if my car goes away. I still have wheels That doesn't make sense So we have this but we don't really use it that often you try to avoid it if you can In fact, if you have to use it you start questioning like did I do something wrong? And although i'm showing you standard shared pointer, we actually don't use that in chrome We use uh base shared ref. It's basically the same thing though Okay, yeah, and I told you that most of the time we don't actually want to use a standard shared pointer So the alternative to shared pointer is unique pointer makes sense. There's only one owner. It is unique And you can't make copies of a unique pointer obviously because then you would have multiples and duplicates and shared ownership So what you can do is move it and remember earlier when I said If i'm taking ownership of something Somebody could call my function and pass me ownership of this pointer And that would still be unique if they no longer have this ownership So it's it's all sort of tying together Um, and then yeah when the only reference is destroyed the actual object is destroyed So it's kind of like a garbage collected language where you can only have one reference at a time. That's kind of how it would work Okay, and I mentioned, you know, you can't actually make a copy But you can't pass ownership the way you pass ownership is with Standard move as to be moved up there. That is a way to say i'm completely done with this. I'm going to pass it off to somebody else And if you want to learn more about this standard move and the whole like passing ownership Uh, here at google we have a class for c++ 11 where we cover this Or later today, I'll be giving a talk called c++ memory, but if you look at your um badges I changed the title late and on your badge it'll actually say c++ 201 move semantics So you can learn more about it then