C++ for C programmers — lesson 1 (classes, constructors, methods, templates, is it efficient?)

C++ for C programmers — lesson 1 (classes, constructors, methods, templates, is it efficient?)

Hello everyone, this is Bisqwit.
The topic of today’s video is C++. Many people who watch my videos have some background in C programming, or at least they know some other programming language that is descended from C.
This video, possibly to become a series, is for people who already know C, but would like to learn what is the big deal with C++. The C language standard I go by is ANSI C.
Nobody, who really still prefers to use the antiquated K&R syntax,
can seriously claim that they can’t read ANSI C. ANSI C has been around since 1989 after all. This is an example C program that implements
a bidirectional linked list, which is a commonly used data structure that
provides fast insertion and fast deletion, but linear-time searching.
Only the most rudimentary operations like insertion, deletion, iteration
and cleanup are provided. The main program demonstrates those basic
operations. This program will provide the framework and
foundation for today’s lesson. Before we switch to C++, let’s save the program,
compile it and run it. C++ was originally called “C with classes”,
that’s how it began. Now a class in C++ is just the same thing
as the struct. class is struct. The big deal with classes is that they may
contain “methods”. A method is a function, declared within the
struct, for dealing with the struct’s data. These functions automatically receive an invisible
parameter, a pointer to the struct instance itself, called “this”.
This is why they can use the struct members without a pointer. Compared to the equivalent C code, this results
in significant simplifications that make the code both easier
to read and write. In C++, structs can also be nested,
for the purposes of limiting the scope in which it can be accessed.
It helps avoid namespace pollution a great deal. Now we can use a simple name like “node” for the list nodes
without fear of collision with existing names in the global namespace.
To access a scope-limited name outside its scope,
you must use the double-colon syntax to explicitly specify which namespace you are accessing. Structs are now proper types. A typedef statement
is no longer needed to turn a struct name into a type name. One of the major points of attention in C++
is initialization and deinitialization. C++ calls them constructing and destructing.
Our init() method becomes a constructor, and our done() method becomes a destructor.
These methods are written in special syntax. The “new” keyword, new in C++, does both memory
allocation and constructor calling. The “delete” keyword,
conversely, does both destructing and freeing at once. However, unless you are implementing data
structures like this program here, it is very rare that you actually use the
“new” or “delete” keywords yourself. A much simpler way to create objects is simply
to declare them. Our main() here does just that. When the object is constructed, the constructor
method is automatically called. We no longer need an explicit call to “init()”.
Similarly, when the object goes out of scope, here denoted by the closing curly brace,
the destructor is automatically called. We no longer need an explicit call to “done()”. There is no memory leak in this program. Now, what if we need a linked list for some
other data type than integers? That’s where templates come in.
In C, this would be difficult. In C++, just a couple of changes is enough. The bracket syntax in main() here is called
“specializing”. We “specialize” the list template for two
datatypes, int and pointer to const char.
These two specializations are distinct types, but they are
implemented by the same source code. The template is a little bit like macro, but
much more sophisticated. Now of course, a linked list is one of the
hundreds of things already found in the C++ standard library.
This is why in C++, you almost never need to deal with
memory allocation and deallocation. Opponents of C++ often bring up the question
of performance. What is the cost of all this abstraction?
Let’s study the assembler listing of the iteration loop of the C version first.
These colors and arrows help you match the C code to the assembler listing.
Now what happened to the code when it was translated to C++? Here we go.
Whoa, it didn’t really change that much. How about when we introduced templates?
Huh. That’s still almost completely identical to before.
Okay. Now let’s see the version that used the standard library!
Hmm… Do you see the change? A couple of instructions changed a bit,
but it’s still basically exactly the same code as the C version was. Conclusion: Rewriting your code for greater
clarity, greater reusability, and greater extensivibility
by translating it into C++ will not hurt the performance. Now this was just a short summary that only
stratched the surface of what C++ is good for. Maybe I’ll make more
in the future, who knows? Anyway, thanks for watching. See you next
time! Bye!

77 thoughts to “C++ for C programmers — lesson 1 (classes, constructors, methods, templates, is it efficient?)”

  1. This video is very nice. It think it gives a good summary for first timers. I personally never used C++, but I hear the real challenge is in the the standard library and learning all the new things it has to offer. Can you confirm this?

  2. Can you or someone else tell me why the hell C hasn't references till today? Pointers have loss of time, so it isn't an answer.

  3. Yes, please more of these.
    that was a great video and the explenations were good although you could probably be more specific about the use of certain language features and that is my biggest complaint actually with c++. I tend to find other languages much clearer, even though I prefer java, c and c++ nowadays to do remotely anything.
    I started with java and then went my way over c, tried a bit of functional languages, (I can use the basics of the dyalog APL dialect,) just to end up with c++ and I really like to use c++ nowadays, although I have sometimes struggle with it, especially the Template programming and namespace use.
    I tend to find namespaces as a concept too weak, knowing the advantages of packages from java, like for example actually making code unaccessible(using the protected keyword) from outside a package and therefore having implementation hiding by just adding or altering one word.

    I once wrote a 2D physics engine in java and I really learned to appreciate the modularity you can have with this. You are just not supposed to acces all the gazillion member-variables of an object that are only used for pyhsics-calculations and if I have a wrapper for them you are also not supposed to acces that. Code that modifies this stuff belongs in the physics package. period. If you want to modify it from outside, then you are forced to do it through some well defined measures. Someone who did not write this could have a hard time understanding the things going on and the variables and names could all change in future so if I refactor code here everything breaks somewhere else where I have no control? nononono. So this is a far better option than raw manipulation from outside imho. Also not "seeing" all these members simplifies the use of a class greatly to my experience. This kind of clarity really helps when programming.

    In c++ the ways to do implementation hiding are numerous but I tend to use a variant of the "Pimpl" method, which means using a protected Constructor and a pointer to the actual implementation, which is actually a derived class of the original class of wich I return an instance when I actually want to create the real thing, and also inlining the whole story so I don't have a performance penalty from using virtual methods because I actually deal with the child class of the original everytime I pretend I use an instance of the original but this is so painful and inconvenient and verbose compared to using just the "private"-keyword in java that I could go nuts about it everytime I do this.

    I also dislike the notion of having header files tbh, and Template-programming where you have to have actual code in header files is kind of repulsive to me.
    I really like c++ but dislike a few things that I really find hard to wrap my had around.

    If you would do more of these videos that would be great and if you could go on some of the "best practices" you have that would be great as you seem to have a lot of experience with c++.

    also I'm sorry this turned into a rant about what I don't like about c++. Your video was great 😉

  4. Don't be so quick to conclusions bizquit. There are tons of stuff you disregarded when you said c++ is easier to read and write, more usable and extensible compared to c. Any longer experience with c++ has you writing tons of boilerplate code, you typically have the exception hell problem, and if you do any serious programming you actually want to control memory allocation and not let it be handled automatically. Those are just some of the many downsides with c++ I can think of. You are a clever guy so think it through until next time.

  5. Great video, thanks for makng it! That would be great if you made more. I found myself having to pause and go back a bit to see exactly what you were doing because it was going a bit fast, but at least for this video that wasn't a problem because I was able to figure out what exactly you were doing after going back a bit.

  6. When you declare an object without using the "new" keyword, that objects gets created on the stack. When you use the "new" keyword, you get a pointer to the object in the heap. What are the pros and cons of each way of doing things? Allocating on the stack means you don't have to manually manage memory, but for some reason all of the courses I have taken seem to teach us to allocate objects on the heap. Why is that?

  7. As usual good old Bisqwit give as great tutorial, your tuts are specific, every topic you touch is covered in detail, you always go through higher languages through lower and back, and that's why i love it 🙂 

  8. Great Bisqwit, I love you ! :D. I just know some of C, enough to deal with such data struct that you shown. If you allow me to give you a humble suggestion, try, if possible, to put legends on your videos, because I'm not fluent in english yet and it's a painful process to me try to understand what you're saying specially due your accent. just a suggestion. But thank you for the video !

  9. I really enjoy your videos. The "live coding" aspect of them along with the tunes you usually have playing is quite soothing to watch. 🙂

  10. Nice tutorial, Bisqwit. I can't wait for the next lesson.
    By the way, why you choose C++ over the other programming language, and how long you mastering it?

  11. @Bisqwit A small correction: what you refer to as a 'specialisation' of a template around 4:15 is actually an instantiation of a template. A specialisation is when you special-case a template for a particular parameter. The vector<bool> specialisation which makes it much more efficient is an example of a specialisation of a template. 

  12. This is exactly what I wanted. Thank you so much for making this. Very concise.

    Most tutorials just drag on and on and frequently go into too much detail about the example application I feel.

  13. Really clear explanation, I love it. I would really appreciate it if you could do some tutorials on data structures (e.g. Binary Search Tree, AVL Tree, and such..) Thanks again xD

  14. Next episode should talk more about classes.  Specifically, the things you noted in the description and polymorphism: abstract classes, virtual functions, and explicit keyword.  And header vs implementation files.  Maybe that's too much for one episode though.  There's a lot to say about C++ objects.

  15. What program is that? I don't see it on your channel description and I'm new to your channel. Though, gotta say, you're pretty great at programming. I'd put myself towards intermediate (worked with 3D, networking, buffers, surfaces, intermediate stuff)

    Oh also, what is a header? I still don't know what it is/does.

  16. I really like you videos and the music you play it's very soothing. Makes me feel sleepy at times though lol The only probel I have is that it is all way, way over my head. I wish I understood it all.

  17. Brilliant video that shows a C program for linked lists, translated into simple C++, then with templates added, then replaced with standard library. This progression and the (somewhat hard to understand) narration is one of the better descriptions I've seen.

  18. Hi Bisqwit, I got a random C++ question: What exactly happens when you run a program with a debugger active?

    I ask this because I have attempted to create a Minecraft clone. It works really well for the most part, except for a few odd bits.

    For example, the main problem is random holes all over the terrain:



    Now, the weird thing is: It works perfectly while I run it with the debugger active (I use MinGW):



    Notice there are no holes. The chunk of terrain that is black is just the one directly below the camera.

    It has been bugging me for hours now, I do not know enough about deep compiler level C++ to know what on Earth causes this kind of behavior 😛

    So do you have any idea what sort of thing would case that? If it helps, the source is here, along with some implementation details at the bottom of the page:


  19. Thanks for FINALLY showing why C++ is any good apart from not having to use formats in printf! As well as explaining what templates are – every C++ book just goes right to classes and does layers and layers of abstraction that make absolutely no sense, just for the sake of being cool and using OOP.

  20. You completely missed the point on the performance question. Of course the final result is the same with optimization flags enabled. But how long did it take to compile both versions? The C++ one is a LOT slower to compile.

  21. Id love to see a long video on all the different ways variables and arrarys and anything else that can be used to manage dynamic data.

  22. Bisqwit I don't know if you still around but I'm honestly a beginner with programming I'm in college now, learning different programming languages but something I worry about is that I don't know what to code to learn more about what c++ can do. Some people say you can code anything which is true but I don't know what interesting to me sadly.

  23. Hah, does anyone know how he is able to write such a complicated syntax that fast? I mean… this might be simple for him but I'm checking the clock on the top right corner of his desktop and even when the seconds pass as they do in real time he still types too fast for an ordinary person.

  24. not to nitpick on a 4 year old video but here's my two cents. I do C exclusively over C++ because it's minimal and C has different grammar than C++. C is more readable than C++ because of the fact that C is so explicit, everything that will happen in the code is right in front of the programmers. In C++, that's not always the case, the heavy abstractions not only hide the complexity but also hides execution such multiple and inherited destructors. In a small program, there's very little difference between C and C++ code but the performance difference really glares when you compare medium to larger scale programs, especially if your C++ classes use alot of virtual methods as opposed to using simple function pointers in C structs.

  25. Given that C++ is much more powerful than C, do you think it is still useful to learn C? What are some cases where people would opt to use C rather than C++?

  26. I just felt like programming for a change, and brushing up on how a "list" internally work, using your C code really helped clearifying the internals of a list that is somewhat equal to std::list. I think the most confusing part of how iteration works in C++ is the list::end(), which you wrote as "return NULL". The conflict here is that you send in a list object (pointer to it), but never use it and return a constant NULL, which I wonder if it could have been redesigned or if it is required for iterating more complex std:: objects? I kinda already know the answer: Too many checks for NULL required for a simple loop, but still. It feels like it could be more clever made, somehow?

  27. Well, dear Sir, that was the most gentle way to say "Aw, cut the crap already!" to the all the people telling that "C is soo much faster and efficient than C++". Even John Carmack admitted he didn't use C++ in the first place because he didn't knew better (source: http://fabiensanglard.net/doom3/interviews.php#qc++). Well played Sir, well played!

  28. Ey, bisqwit. Your windows fonts look really smooth. You can even notice it in the video. Is it because of the 4k screen and windows scaling options?
    I just found out your channel and it's awesome

  29. If YouTube algorithm have been fixed a couple of years ago, I didn't have to wait this long for this.

  30. me after study my ass off of C and think to myself "now i finna understand something on that finnish guy's videos" came here, 20 secs, strong headaches, don't understand shit after 5 lines of code.

  31. Thanks for it!. I'm learning C++ because most of the documentation of opengl is written with this. But I only know C.

    Why is necessary use auto in C++? Why isn't better just declare the real value of that variable?

  32. I would love to see a 'C for C++ programmers' video. Most of us who learned C++ often rely too much on the nifty features and algorithms of its standard library and we turn into babies whose pacifiers have been stolen when we use C without these abstractions.

  33. I posted a comment here earlier regarding your implementation of the linked list and a question I had regarding it, but I deleted it because I figured it out. Basically, when I read your code I didn't see your constructor and thus I didn't see that you null-initialized the *first and *last pointers. Thus, I was confused when I read this line

    if(newnode->prev) newnode->prev->next = newnode;

    Since I didn't see the constructor and the null-initialization of the first and last pointers, I assumed this if statement would evaluate to true and then proceed to dereference garbage. All is good now, though!

  34. I don't use C++ because when you take away all of the features that I don't use, it's basically C.

    1. "using namespace" is considered evil, so why have namespaces? Use "_" instead of "::".

    2. RTTI is useless, so I turn it off with "-fno-rtti".

    3. Classes are just structs. No need for em.

    4. Rather than writing move/copy constructors for everything, why not just opt IN to construction using an "init" function or macro that constructs it like `#define foo_of(x, y) ((struct foo) { x, y })`.

    5. I avoid destructors, because it's sometimes unclear when they're going to be called. They cause more problems than they solve imo. Just look at unique pointers. Ugh. No thanks. Calling "free" isn't rocket science.

    6. If my naming convention is to label private members with a "m_" or "_" prefix, there's no point to using public/private for encapsulation outside of aggressively enforcing policies that are prone to change. Signaling intent is enough.

    7. Using public/private to control which methods are overridden with inheritance is stupid when you already have overloadable functions. In C, just encode part of the type information in the name, like "update_player(…)". This is how C++ does it, just crazier, like "_Z6updateC6playerv".

    8. I use templates as little as possible because they generate mountains of code, are slow to compile, and often difficult to read. Also, if I'm going to have to put code in my headers anyway (due to necessary inlining or linking issues), why not use macros and static functions? It works just as well as templates. Often, I'll use void pointers and function pointers like how bsort and qsort work.

    9. I avoid exceptions because it violates the high-level structure of the code. Everything becomes a potential point of error, including the object creation/destruction. I'd rather pass around an error callback or utilize a return value.

    10. I don't like type inference in a statically typed language. Some would make the case that you don't have to type the name twice when using a constructor, so you can do "auto foos = std::vector<foo>();", and these people apparently don't know that you can do "std::vector<foo> foos();".

    11. I don't like standard iterators, though the for-loop syntax is nice. It's MUCH easier imo to have a function that takes a "yield(value)" function as an argument. The code is waaaaaayy simpler.

    12. I don't like standard vectors. No arguments about quality or performance, just I have a better library in C that uses macros instead of templates and interoperates seamlessly with arrays.

    At this point, the only things I'm losing are the implicit lvalue / rvalue conversions you get from having references, scoped enums (enum classes), and initial struct values. These are things I can live without.

    Perhaps the biggest argument of all is that I absolutely HATE reading other people's C++ code. That's not a testament to bad programmers btw, it's a testament to bad syntax.

  35. This is a brilliant demonstration. Maybe it was "cherrypicked" but upgrading to a template was astonishingly simple and powerful

  36. Hi Bisqwit! It would be great to see the continuation of the series of these videos! And by the way, where can I get the Joe editor for windows, working in cmd?

Leave a Reply

Your email address will not be published. Required fields are marked *