C++ for C# and Java Developers

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
Right! You saw the title. So, I’m not going to do any long intro or anything like that. This video will tell you about all of the things about how to transition from a language like C# or Java into C++. Now, this video is not going to go over the basic stuff like “How do I print to the screen?” You can just Google those little things. But this video will cover the more complicated things you will face and be very confused by when you hop into C++ coming from a more managed language. OK, enough of that, let’s play the intro! OK, don’t copy down any code I type, just watch the video since a vast majority of this is theory-like stuff. Right, let’s start it off with the compiler and linker. So, we all know what the compiler is, I won’t get into that. But, what about the linker? Well, in .NET and Java the linker isn’t something that you hear about, because everything is managed we don’t need one, or at least, the one we do have is built into the compiler, so you never see it. The most important thing that you need to understand, and this especially comes in play on the next topic, is that to the compiler… All of the files in your project are separate. So, let’s say your project is split into 3 files. The C# compiler would essentially look at all of these files together, and it will work out what refers to what, all of that happens within the compiler. However, the C++ compiler doesn’t work like that. It takes in one file and it turns that file into an object file. And it does that for each file, so, now, if you look at this – we have three compiled files. So, the code has essentially been compiled to machine code, it’s just that they’ve all been compiled separately. But this is one big application, so, how do we now join all of these files up into one big executable file? Well, that’s what the linker does. You just give the linker a list of object files and it will put them all together. Now, sometimes libraries come as object files, and these are called static libraries, so, you just link in the library so then the library itself essentially becomes a part of your executable. Static libraries don’t exist in C#, because, well, there’s no linker. C# has dynamic libraries (as you can also get in C++), which means they are separate from the executable file, so, the C# program, as it runs, would read through those DLLs to find the method it wants, this is one of the reasons, why C++ is can be faster than a language like C#. OK! Well, this brings us very nicely onto header files. So, if these are all separate things, how do we refer to something in another file without the compiler giving us an error? So, let’s say I define a class in the “MyClass” file. If I want to refer to that class in the “Program” file, how would I do that, if they’re all separate? Well, what we do is we use header files. So, let’s actually look at a project that’s laid out like this, now, I’m using Visual Studio for this video, but obviously, use whatever IDE you want. Now, as you can see, if you look over here, the project is split into 3 files. And in our “Program” file we are referring to a class called “MyClass”… “MyClass” is defined in the file called, well “MyClass” and it contains two methods within it, one adds two numbers and returns the result, and the other just returns 3 because I’m clearly very creative. Now, as we might expect from what I just explained trying to access this class from outside this file, like in the “Program” file gives us an error. Because, each of these are compiled separately from one another, so, this “Program” file when compiled won’t see anything outside of it. So, we have to think a bit differently, because we can’t make a class like this. So, firstly, what we need is a header file, which is a file ending in “.h”, sometimes you can also end it in “.hpp” for C++ projects so that you can distinguish between C header files and C++ header files. So, something like this, and within this header file we make an outline of our class, “MyClass”. And what I mean by an outline is that we don’t include any of the code, just a list of all the members the class will contain. So, the outline would look like this. So, now, anywhere that we want to use MyClass, we have to include this header file in. So, within my “program” file, I’ll add an “include” for “MyClass.h”. Now, this include here is nothing special. In .NET or Java a lot is going on when we use things such as “using”. But, in C++ literally, all include does is it copies the contents of the “MyClass.h” file and slaps it right here. That’s literally it. So, it looks for a “MyClass.h” file and if it finds it, it takes everything within that header file and it puts it here, if it doesn’t find one, then that’s a compiler error. So, technically, I could actually just copy and paste the stuff inside the header file, paste it in here and delete the “include”, and this is identical to using the “include”. That’s why it’s a pre-processor definition, which you can see by the hashtag there – it copies across the data from the header file first and then everything gets complies. Now, there are actually two ways of using the include declaration – one is with quotes, like this, like we just used, and one of them is with angle brackets, like this, and you usually use this to access some kind of system header file. So, for example, if I want to use the Windows header file, which contains an outline of all kinds of methods for things such as opening windows, that of course, later on, get linked in. Then, I would write it with angle brackets. What these technically mean is the angle brackets (generally, this is in most compilers) will search for this header file in the system directory first, while the quotes will search in the local project directory first. So, the quotes will search in the same folder as the “Program” file in this case. OK, now, this header is only half of the solution, we’ve made an outline of the class’ members, but now, there’s an issue with this, we are now declaring this class twice: once in the header file, and once in the actual “MyClass” file, we can’t do it like that. So, let’s just delete all of this, and we’ll just keep hold of the methods. Now, this alone isn’t enough, because all we’re doing here is we’re making two methods that are outside of a class, which is actually possible inside C++, you don’t need to have methods inside classes. What we need to do is we need to say that we’re providing the code for these within methods within the “MyClass”, and to do that, before the method name, we write “MyClass” and two colons, just like this. Now, of course, that’s going to give us an error because as far as this file knows, there isn’t a “MyClass”, so, the final step is to just include the “MyClass” header file, that way C++ can recognise what “MyClass” we’re providing the code for. So, this is how you make a class, you outline all of the members in a header file like this, and then within a C++ file, you actually provide those methods’ code. So, now, when this file gets linked in, it will fill in these methods’ bodies. OK, let’s move onto one of the most fundamental concepts, the pointer. So a pointer is a small object, it’s just like any other object really, in 32-bit machines, it will most likely be 32-bit and in 64-bit machines, it will most likely be 64-bits. Technically, a pointer is nothing but an integer, but, the reason we distinguish a pointer between a normal object is because of what it does. Quite simply, it points towards a specific location. So, let’s pretend this line here is our RAM… And it’s split into each of the bytes. Let’s make a pointer that points towards position… 3. Now, if we were to look at the bits that make up this pointer, it’s just a “3”. But what we can do is we can dereference this pointer. So, that means we take a look at position 3 in the RAM and see what’s there. In C++, and C, and even in unsafe C#, you can represent a pointer type by writing the data type you’re pointing at, followed by a star. And to generate a pointer towards something, like a certain variable, we can use an ampersand. Let’s take a look! And, all I’m going to do is make an integer called “a”, so, there are no pointers here or anything like that yet, then, I’ll set it to “7”. So, exactly like you would normally do in C# or Java. Now, this number is of course somewhere in the RAM, right? Well, what we can is we can make a pointer to that position, to that place this “7” is in, within the RAM – so, let’s do it! So, this will be an integer pointer, because it’s pointing towards an integer. What that “int” really means is that it’s going to point towards the RAM in 4-byte intervals, because an “int” is 4 bytes big, so, if I pushed this pointer forward by one, it would move forward by 4 bytes. Now, let’s call this “b”. And, finally, we will now make it a pointer to the variable “a”, just like this. So, this ampersand, like I said earlier, will make a pointer towards the variable “a”. So, now, we have a pointer to the variable “a”. We’ll play around with these two in just a moment after I cover a bit more theory! Now, what happens if I write “b++”? You might expect it to increase our number, 7, right? Because “b” is pointing towards that “7”, surely it would take what it’s pointing at and increase it by one? Nope! What “b++” would actually do is it would add one, not to what the pointer is pointing towards, but to the pointer itself. So, if we imagine our variable “a” is at position 20 in RAM. Instead of increasing that “7”, the pointer itself, will move up by one. Now, since it’s pointing towards an integer, and integers are 4 bytes big, it will technically jump forwards by 4 bytes. So, now, it’s pointing towards position 24. Yeah, that didn’t increase our “7”, now, if we’re not careful here and we try to set at the position this pointer is at now… We can potentially corrupt some stuff we didn’t want to corrupt – don’t worry, you generally can’t access memory outside this application, so, the worst you’ll do is corrupt your application’s current memory… But, of course, that’s still not ideal! So, we don’t want to increase the pointer we want to increase what the pointer is pointing at! And, to change the value the pointer is actually pointing to, you have to dereference it. I mentioned this earlier. So, to do that, you just write a star before the pointer. So, if I wanted to change the “7” into a “13”, I can just write “*b = 13”, that’s dereferencing and setting that dereferenced value. So, with all of this knowledge, let’s play around with some things in C++ and explain why they work that way. Firstly, let’s dereference and increase variable “b” – what will the value of “a” be? And what will the dereferenced value of “b” be? Alright! Let’s take a look, with a little bit of debugging. So, the value of “a” has gone up to “8”, of course, it has, the pointer “b” was pointing towards variable “a”, so, when we dereferenced it and incremented that by one, we pushed whatever it was pointing at up by one, and it was pointing at “a”. Now, let’s put our mouse over “b” and – whoa! Now, I know this might look super overwhelming – I mean, what is this number? But it really is quite simple. This is the value of the pointer itself. So, this is the position in RAM that the pointer is pointing towards. This is wherein our RAM the variable “a” is stored. Makes sense, right? But, we don’t want to look at the pointer itself, we want to look at the actual item it’s pointing towards. So, we need to dereference it. Thankfully, the debugger will usually let us look at it dereferenced, in Visual Studio it’s simply by expanding it out like this, of course, this may vary by your IDE. The next thing you can also do with pointers is look at a certain offset ahead of it. So, if I have a bunch of integers in RAM like this, and I want to just look ahead of where this pointer is. I can use square brackets, kind of like you normally would with an array, so, if I write “square brackets 3” then that will look 3 places ahead, and this is dereferenced, so, this does actually look at the value three places ahead. This doesn’t change the pointer, it just gets the value. Now, why are pointers so essential to C++? Well, let’s take a look. Here I’ve just made this completely random class. Don’t worry, I’ll talk about the syntax of how you write classes at the end, this is just to demonstrate. Within this class though you can see that there are 8 integers. Now, there’s a thing in C++ called “sizeof”, that tells you how many bytes big a particular data type is. So, why don’t we find out how big our class is, like this? We can predict that this will give us 32. Because, integers like this are usually 32-bits or 4 bytes and we have eight of them. So our class here is going to be 32 bytes long – 8 integers! And just to prove that, take a look, “a” is set to “32”. Our class is 32 bytes big. Let’s say I now made a method, let’s call it “MyMethod”, and this takes in our class, let’s call this parameter “myParameter”. This is bad code right here instantly. This method is asking for our class, that means the entire 32-byte class, unlike in C# or Java where it’s basically just passing pointers around to your classes, this is literally taking in the entire 32-byte class. So, let’s make a variable called “a”, that is of my class’s type, so, this variable will store my entire class, then I’ll pass this variable “a” into my new method. Now, yes, this is actually initialized – so this isn’t null like in C# or Java, this is actually initialized, and I will get to that later, that’s an important point for later. Now, look at what’s happening here, I am now giving “MyMethod” an entire copy of my class. I’m taking all 32-bytes of it and copying the class across – think about how wasteful that is on both the CPU and our memory usage. So, I now have one copy of the class in variable “a” and another in the variable “myParameter” – we are now using 64-bytes of data, for the same object! However, we can fix this easily. Instead of making this take in our class, we make it take in a pointer to our class. So, now, instead of carrying around our entire 32-byte object, the only thing it will carry around is our pointer. And all the pointer is just a 4 – 8 byte number. You can imagine that that’s much more performant than passing a copy of the entire object around. And, this is why pointers are so essential to C++, they are important for performance and they help you keep references to things as opposed to copying things. OK! I’ve made a lot of changes around here. Now, you know how I kept on saying that it will make a copy of the entire class? Well, you have to be careful, because if the class contains pointers… Those pointers will still both point towards the same thing. Here, I have two classes. The first class is still just 8 integers… But, the second class has a pointer towards the first class. I also have two variables here, “a” and “b”, and, once again, unlike in C# and Java, I don’t need to initialize them. And, I’m changing the “firstClassPtr” variable in variable “b” to a pointer to my FirstClass, so, pause the video now if you need some time to just work out what’s going on in this code so far, and then I’ll move on. Right, and now, I’ve got “MyMethod” here that takes in the SecondClass, not a pointer to it. Now, this is important. Let’s take the “firstClassPtr”’s first integer within “MyMethod”, and change it to 14. Right! Firstly, let’s stop it right there, what is this arrow? Well, it’s literally just dereferencing a pointer and accessing a member on it. So, we need this because if we look within our SecondClass… The “firstClassPtr” variable is a pointer! So, in order to access the values on the FirstClass this is pointing to, I have to dereference it first, and the arrow just dereferences it while also accessing the members in it. It’s the equivalent of writing this essentially. Now, will variable “a” change? So, will the first integer in variable “a” change at all? And, even further, will the first integer in the “firstClassPtr” field in variable “b” change at all? Keep in mind that this right here is not a pointer to the SecondClass. Now, the answer is actually… Yes – it will. Which might be a bit confusing, because if I don’t make this a pointer, surely it’s copying across the object. Yeah, you’re right, it does copy across the object. It will copy all of the members within the “SecondClass” – now, the “SecondClass” only has one member in it… What is that member? It’s a pointer… What did I say right at the beginning a pointer really is? A pointer is essentially just an integer. So, when we “copied” our “SecondClass”, all we copied was the pointer itself… Not the value it was pointing to. So that means it points to the same class, the same instance of that class as the variable “a”, so, the pointer itself, the 4 – 8 byte pointer has been copied… But, it’s still pointing to variable “a”. And this is so important to understand, this is why languages like C# and Java are so easy by comparison. And just one more thing, I want to quickly mention, there’s also something called a “void*” and it’s basically where it’s pointing to something, but you have no idea what it’s pointing towards, so, it’s kind of like the equivalent of “object” in C#. Now, you can’t do anything with that pointer, you have to cast it to something else if something does give you a void pointer, because how is the compiler supposed to work with that? When you write this how does the compiler know how many bytes to move forwards when you increment that pointer? It doesn’t! So, that’s what void pointers are, and when a method gives you a void pointer, it’s essentially expecting you to cast that over to the correct type of pointer. Alright! Now, let’s move onto the Heap and Stack… So, the Heap and Stack are the two important blocks of memory in your RAM. One of them is super simple, and one of them is fairly complicated. Let’s start it off with the stack. The stack is exactly what it says it is, it’s a bunch of items all stacked on top of each other. And normally you can push and pop from the stack. That’s all it is – it’s literally just a list of items… You can’t remove from the middle of it, though, and that’s quite important. You can only really remove from the top of it. Now, this is important. The stack will lose all of its items when we leave a method. So, let’s say within a method we added 4 items to the stack… When we return from that method, those 4 items are automatically popped off the stack. That’s called the stack frame, it’s the current section of the stack that is dedicated to just our method, so, as soon as we return from whatever method this stack frame is for, that entire frame gets removed. So, what actually is the stack, as in, where does it come from? Is it provided by the operating system, or what? Well, it’s doesn’t really “come from” anywhere. Essentially, when you compile your application, it will generate instructions that pushes and pops to this “stack”. There’s no built-in function to the operating system that does that or anything, your code itself when compiled will contain the correct instructions to do the things in the stack. Now, I was originally going to show you the decompiled instructions of our application at this point… But, I decided that it was a bit much. So, let’s not do that, but, if in a future video you would want me to take a much deeper dive into the stack and how it really works, and start looking at the compiled instructions that make the stack become a thing, then please tell me. OK, now, what data actually goes on the stack? Well, any local variables. That’s it… When you make a local variable, it goes onto the stack. So, if I write “int a = 20”, that’s putting the number “20” onto the stack. That means if we made a pointer to “a”, and we tried to return that pointer to another method… We would probably get a garbage value – because it’s been popped off the stack! And, literally any local variables you make will go onto the stack. There’s also some extra data like the return address that goes onto the stack, so, that way when you return from a method, it knows exactly which instruction to hop back to since it is right at the bottom of the stack frame and it also puts the position of the last stack frame in there too, and other things that go onto the stack will be all of the arguments, and the return values of the methods and things like that. So, technically it’s not entirely local variables, but, from what we can see in our code, and from what you really need to know, it is just the local variables and arguments. So, this is why there’s an issue with passing around entire objects. When you pass an object around directly like this. That object is going onto the stack. However, if we pass a pointer to something then only that pointer will get copied across the stack, as opposed to the entire object, and that’s the difference. Alright! This now brings onto one of the differences between C++ and a managed language like C# or Java, which I talked about earlier. I have a class, called “MyClass”, once again, at the end of the video I’ll get into the syntax for all of these things. And then, I do this, so, I make a local variable of type MyClass in some other method. Now, in C# or Java, that variable “a” will be null, won’t it? We haven’t initialized it yet. In C++, that is not the case, this variable has just initialized itself onto the stack, so, after this line of code “a” is now on the stack. Now, if I add a constructor to my class, that let’s say takes in an integer, and sets that integer, then I can call that constructor down here by writing the brackets after the variable name and providing the arguments. Yeah, I know, this is quite different from in C# or Java, but it still makes sense, because it’s instantly initializing the class, we have to be able to provide arguments to a constructor, and this is how we do it. OK! Now, let’s modify this slightly here. I’ve added two methods, take a moment to just get familiar with these two methods. OK! Now, I’m going to show you what’s happening on the stack in this code… Just to be sure that we get this idea absolutely down, and we don’t have to think about it again, because as we get into the heap, you’ll need to already have a very good idea of how the stack works. OK! Now, let’s have a little stack here and change it as we run. So, this is our stack, and this little outline here is our stack frame – so, let’s go! So, when we run this line of code, what we’re going to do is we’re going to make an instance of “MyClass”, now, in this scenario “MyClass” is actually a good 16 bytes, as we have four integers in it, but that size could vary of course based on the class. So, when we create our variable “a”, we are adding that to the stack. And, that’s it. No pointers are involved here or anything, that’s fine. Then, we call the “SecondMethod”, and this method takes in a raw “MyClass” parameter. So, C++ will put in the extra data it needs, such as the return address, and we change the stack frame… And we now have to bring in the parameter, which, of course, since we aren’t pointing to it or anything, will involve a copy of the entire object, like this. So, now, we have the same object twice. Then, we take our second object and we change the integer within it to 123. And, then, when we exit that method, we then remove that copied object off the stack frame – use the extra data provided to us to help adjust our stack frame and point the program to the right address. And, since that is now well out of our stack frame, it has essentially been popped off the stack – and that class was gone. So, technically, this was completely pointless, we modified an object that would just get popped off later anyway. However, if I made the method take in a pointer like this, it would be different. Remember, that I’m using an arrow here in order to dereference and access members all in one. So, now, if we look at the stack, when we run this line, we add our “MyClass” object onto the stack, and then, when we go into our method, we make a pointer towards that object, and put that very small pointer onto the stack. So, now, when I modify the value in that pointer, it’s modifying that item on the stack. Alright! I think we’ve definitely gotten the concept of the stack down, next, let’s focus on the heap. So, what data goes onto the heap? Well, for every single line of code we’ve written so far, nothing has actually gone onto the heap. I’ll get into how we put objects onto the heap, but I want to explain what the heap actually is first. So, the heap is a bit smarter than the stack, but more complicated, before we look into how it roughly works, just like with the stack, where does it come from? Now, unlike with the stack, the operating system actually provides the heap, well, that’s oversimplifying it a tiny bit, but, essentially, roughly if you look within the source code of an operating system that has support for a heap, you’ll find code in there that actually makes up the heap. So this meant this if you were compiling something under no operating system, like you were actually making an operating system (just as an example)… You wouldn’t have a heap and you would have to make one. So, what’s the heap all about, then? Well, the heap is just a big chunk of memory. And what can happen is you can slot different objects in and out of there, and, objects can be removed at any point too. So, basically what happens is your program says to the operating system “Can I have X number of bytes please?” and what the operating system will do, is it will search through the heap, find an empty spot in the heap, and say, “Right, you can have this bit of the heap here”. If there are no spots, then the operating system will of course expand the heap. The heap is shared through your entire application, it’s not shared through your system, and so, each process will have its own heap. Well, that’s generally in almost all operating systems, I mean, really, a lot of how the heap actually works depends on the operating system, it’s just the way you use it that’s universal. So, unlike the stack, nothing gets automatically removed from the heap. So, while with the stack when I exit a method, it pops those items off, with the heap, those items will stay there until we kill our process. And, this is where memory leaks come from, you have to tell the operating system “Right, I’m done with this piece of the heap right here, please remove it”. And it will then remove that item from the heap. But, if you don’t free up that bit in the heap, it will stay there forever, so, if you were allocating lots and lots of objects to the heap all at once, and you weren’t freeing them… Your program’s memory usage would just go up and up and up, and that’s how memory leaks happen. So, before we look at how exactly we use this heap… Let’s look at the advantages and disadvantages of both. So, the advantage of the stack, is that it is fast, seriously, in comparison to the heap, it is blazingly fast, literally all it has to do is just put the value there and increase one number. That’s essentially the big difference between the stack and heap and why it’s technically preferable to always write to the stack, but unfortunately it doesn’t work out like that. Unlike the stack, the heap can grow and shrink, and can contain huge objects, whereas the stack is typically about 4MB maximum in size. And, not only that, but, of course, with the heap, objects don’t automatically delete themselves, now, that can be seen as a disadvantage if you’re not careful but that’s also important because if you want to create one object within one method, and then access that object after that method has returned… You have to use the heap… So, essentially, anything where it could be any variable size, so we don’t know its size in advance, so, typically an array, has to go onto the heap. Right then! Let me now explain how we allocate and deallocate to the heap within our code. Now, this does vary a little bit between C and C++, so, let me show you the C++ way first, and then I’ll explain what the C++ way actually does, which will then bring us onto the C way of doing it. So, in order to allocate a new object to the heap, we write “new” followed by our type of object, and constructor parameters after that, so, exactly like in C# or Java. We write “new” and it will initialize this object. Now, what is different from C# or Java is that “new” returns a pointer, and that pointer points towards where that object is in the heap. So, if I write this, then this will create an instance of “MyClass” on the heap, so, we have a “MyClass” object sitting there on the heap. Then, this “new” keyword here will create a pointer towards that “MyClass” object, so, we can then put that pointer into a local variable, so, that pointer will go onto the stack, because it’s going into the local variable. So, the pointer itself will get deleted when we leave the method, however, the actual object it’s pointing to, that’s on the heap, won’t get deleted unless we free it. So, in order to delete it when we’re finally done with it we run “delete”, and we pass in our pointer… And then whatever is implementing the heap will look at that location within the heap where that pointer is, and the heap itself will keep track of how big all of these things are, so, the heap knows exactly how big this object is, and exactly what chunk of memory it takes up, and so it will just free it up, and now, any future objects we allocate, can now fill this space, no memory leaks. Now, this is the code we write when we want to delete an object we’ve put onto the heap, however, if we’ve initialized an array onto the heap, we’ll get into arrays in a minute, then you need to write “delete[]” like this with square brackets, otherwise you’ll most likely end up only deleting the first item in that array. Now, these “new” and “delete” keywords are specific to only C++, and these are the keywords you should be using in C++ because these make sure that you call the constructor and destructor on classes, which, well, C doesn’t have classes so that’s why these aren’t keywords in C. So, in order to look at how it works in C, we need to very quickly look at what the “new” and “delete” keywords actually do in the background. It’s so simple. When you write the “new” keyword, what your program actually does, when it’s compiled and everything is it calls a method called “malloc” – you might have actually heard of this before, well, this is what “new” calls when it gets compiled, and this “malloc” method is provided by your operating system, once again, oversimplifying it a little bit here, but that’s pretty much what’s going on here. So, when we write the new keyword in C++, it will turn that into calling “malloc”, and of course calling the constructor of our class. Let’s look at this malloc method a little bit closer, it’s really simple to use. It takes in an integer and it returns a pointer… When you really think about it for a moment, you can probably guess what these two will be. The integer is how many bytes you want to allocate, so, if I passed in “100” then our operating system or whatever will then find a space that has 100 bytes and this method will return a pointer to the very beginning of that section in the heap. So, then, we can do whatever we want with that pointer and the 99 bytes that follow it. Now, it returns a void pointer, which I mentioned earlier, so, this means that in order to use, we would need to cast it to whatever type you want to put within those 100 bytes. So, if I wanted to put “unsigned short”s in there, which are 2 bytes big, then I would have to cast that to an “unsigned short” pointer, like this. So, C++ does that for you and works out the type at compile time based on what you write, but, if you really wanted to manually allocate a block of bytes, then I suppose you could just call “malloc”. And in regular C, this is how you would have to do it. And freeing up memory within the heap can be done through “free”, and you just pass in your pointer again here. Right! Let’s talk about arrays. The most important thing that you need to understand about arrays is that they don’t “exist”. And what I mean by that is, there’s no “array” type. So, I can’t write integer array like this – no, there’s no type for an array. The way you store an array is with a pointer. And that pointer points towards the very first item in that array. So, watch this. If I want to create an array with 100 integers on it, I would write this, integer pointer, which will point towards the first item, then the name of the variable, and, then new, see, allocating onto the heap, integer and we want 100 of those. But, C++ doesn’t recognize this as an array, all it is, is just a regular pointer. So, what if I want to access the second item in the array, well then, I need to look ahead of the pointer by 1… And, how do we do that? Remember, we use the name of the variable, square brackets and how far ahead we want to look. So, although this looks and feels exactly the same as using arrays in C# or Java, it’s really not, because it’s actually just a simple pointer. Now, that being said, there is a useful type that’s the equivalent of a list in C#, and an ArrayList in Java. It’s called a “vector”. And this is a managed array type where it will automatically grow as you add items to it. Now, the vector type is inside a namespace, which is something we haven’t had experience with yet, but, it’s essentially the same as in C# and Java. So, in order to use a vector, firstly, we obviously need to have the standard header file included, because that’s where the vector’s outline will be so that we can use this. But then, there are two ways we can access that vector. And, this is very similar in C#. So, the vector is in a namespace called “standard”, which is spelt like this. So, if I want to access a vector, I’ll have to write “std”, and then two colons, and, this is essentially the equivalent of using a “.”, except it works directly on static types. And then I can access our vector. Or if I don’t want to write this every single time we want to access something within the standard namespace I can write “using namespace std” at the top and this will automatically put this before anything that’s in the standard namespace when we compile. So, I won’t go into vectors since this video is getting quite long and it’s something you can easily Google, but you can add to it, remove from it, and all of that, and it will automatically resize, and isn’t a fixed size. Just be aware about deleting vectors though. Now, in this case, the vector, the actual vector itself is on the stack, so, that means the vector will get destroyed when we return from this method. And, the vector will destroy all of the items within it. However, you have to be careful here. Because if the vector is full of pointers, it will destroy those pointers, but not what they’re pointing towards, don’t fall into the trap. Right, let’s quickly hop into strings and then we’ll blaze through the syntax and we’ll be done. So, strings are almost identical to arrays – in that they don’t “exist” as a thing, as an actual type. However, there is a “string” class within the standard namespace that is designed to make working with strings easier. So, ignoring the standard namespace, a string is nothing but a character array… And, in C++, as we know, an array is just a pointer. So, if we write “abc” in quotes like this. This will literally just create a character array with “a”, “b” and “c” in it. This thing literally returns a character pointer. Well, not quite, it returns a constant character pointer, like this, but we can just cast that to a character pointer. Now, unlike arrays where have to just know how big they are and keep track of how big they are. Strings, or, more specifically character arrays typically end with a null character. So, that means that right at the end they have a character that’s just 0. And that is quite important, because that means that if you pass your string to some external library, it will generally expect to see a null character at the end of your string, that’s how it will know that it’s hit the end. Now, when we use a string literal like this, it automatically does that, so no need to worry about this, but if you’re playing around directly with the character arrays, you have to be aware of this. This is how the “strlen” function works – there’s a function provided in the standard library that tells you how long a string is. And, all it is, is just a simple while loop that counts up until it hits a null character, this is essentially that “strlen” function right here, just return I, and you’ve got it. Alright, let’s finish this up, as I’m writing up the script for this I’m being more and more aware of just how long this is getting. Now, there is also a class called “string” that’s provided in the standard namespace that’s designed to make working with string much easier, so, that has concentration and all sorts like that, which you… obviously can’t do with an array. Once again, Google will be your friend there. Right! That’s all of the difficult stuff! Let’s blaze through some syntax points, particularly classes. So, defining a class is essentially the same, but, within the class is a bit different. Instead of putting the protection level directly on the members, like this, you have to move it above like this, and this will make any members below it public. If I then want to make these two private, I could write this, so, I now have public members and private members. Now, inheritance is a bit different too – there’s no such thing as an abstract class, that doesn’t exist. But, you can declare virtual methods within a class. And, you don’t need an override keyword to override the method is the inheriting class, we just write exactly the same method name and this will override the base one. Now, in a proper program, we obviously wouldn’t be putting the code into a header file, but this is just to demonstrate. Now, when you do inherit from a class, you write a colon, and write the word public, followed by the name of the class, if you write “private” it will do a sort-of half inheritance, so, this class is inheriting from this class, but no one else can see it, so, you can’t cast this class, to the base class like you normally could, it’s kind of like an invisible inheritance – just don’t use it, there’s a discussion about it on stack overflow linked below amongst a bunch of other discussions that I think are quite good to read when you’re getting into C++. Right then, that’s it! Yeah, that syntax section was quite short, but we already covered pretty much all of the syntax, now, one thing I did miss out was references, so, with a pointer you write a star after the type, with a reference you write an ampersand after the type. Basically, a reference is the same as a pointer, except for the fact that you can’t actually change the reference itself – it will always point towards a given object, there’s another article down there about references too! And, that’s it! Thank you for watching this video, be sure to leave a like if it was helpful, and comment if, well, if you have any comments. Bye!
Info
Channel: ABMedia
Views: 6,587
Rating: 4.972158 out of 5
Keywords: c++ for c# and java developers, learn c++ for c# programmer, learn c++ for c# developer, c++ for c#, learn c++ for java programmer, learn c++ for java developer, differences between c++ and java, differences between c++ and c#, c++ pointers explained, c++ heap and stack for c# developers, c++ stack and heap for c# developers, c++ heap and stack for java developers, c++ stack and heap for java developers, c# for java developers, c# vs c++, c++ vs c#
Id: GWDJyV04ghs
Channel Id: undefined
Length: 39min 46sec (2386 seconds)
Published: Tue Feb 18 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.