Very nice video, thank you! What do you use for the code and diagram animations at the end?
@CodeForYourself7 күн бұрын
Thanks for the compliments! Whenever you see code animations I use motioncanvas.io The rest of the animations, including the last diagram animation here about shared pointers, I make by creating images with the Apple's Freeform, import them into Davinci Resolve where I edit my videos, and do the rest of the animations there.
@erkamkocaer20978 күн бұрын
why did you use virtual on Write functions for jpegio and pngio at the final example code?
@CodeForYourself8 күн бұрын
That is it make sure that when we call these functions we look up the actual functions to be called in the vtable. In the end of the example we pass a reference to an *IoInterface* object. So try to make sure you understand exactly what will happen when we call *Write* on such an object reference. Does this help?
@erkamkocaer20977 күн бұрын
@@CodeForYourself I understand what you mean but in the video you used "void Write(const std::filesystem::path& path, const std::vector<Color>& data) const override { std::cout << "Writing PNG to path: " << path << std::endl; }" function but on github you used "virtual void Write(const std::filesystem::path& path, const std::vector<Color>& data) const override { std::cout << "Writing PNG to path: " << path << std::endl; }" function for both png and jpeg. I expected and understood first function but did not understand second one.
@CodeForYourself7 күн бұрын
@@erkamkocaer2097 oh! Now I understand! Thanks for pointing it out! It's a bug I have on GitHub. We *can* have *virtual* and *override* for the same functions but generally we should just use *override* as the *virtual* is implied here. So basically what I'm trying to say is that *override* implies *virtual*. I'll remove *virtual* from my GitHub code as it was probably a copy-paste error on my side. Thanks again!
@CodeForYourself7 күн бұрын
@@erkamkocaer2097 I've updated the code on GitHub to not have *virtual* in the last example. Thanks again for bringing it up!
@erkamkocaer20977 күн бұрын
@@CodeForYourself thank you for your attention. I like your cpp videos. They are really impressive.
@Sheeldzy11 күн бұрын
I’ve been watching your channel and following along from the start. This video just helped me tie a lot of concepts together. Many thanks, keep it coming!
@CodeForYourself11 күн бұрын
Thanks a lot! Happy to hear it was useful!
@PerriPaprikash11 күн бұрын
why do a video? why not simple write a nicely written article that people can read at their own leisure, and one where you can correct the numerous issues raised on the cpp subedit
@CodeForYourself11 күн бұрын
That is a valid question. The main reason is that some people prefer a video format and a video allows me to do both, have a markdown article and a video. You can find the markdown under the video. The downside is of course that errors are harder to fix.
@richardbennett436514 күн бұрын
Then, he changed it back again at 6:05. 😂😮😅😅😅
@CodeForYourself14 күн бұрын
@@richardbennett4365 Same explanation as for the first change. The blank T-shirt is the original recording and the “save the earth” one is the follow-up 😅
@richardbennett436514 күн бұрын
Nice, and why did the presenter change shirts at 5:10???
@CodeForYourself14 күн бұрын
@@richardbennett4365 simple. I recorded everything and then, when editing found that the story wouldn’t add up. So had to re-record and add a part. But the old tshirt was already in the laundry basket 😅
@segfault456814 күн бұрын
About the manual delete, I always get questions from friends about whether they should use delete on a raw pointer they got as a return value from a function inside some old C library, It is all super confusing for beginners. Usually Documentation have it mentioned as "non-owning". It's amazing to see how all over the place each library's cleanup methods are.
@CodeForYourself14 күн бұрын
@@segfault4568 yes, my experience exactly. That mess is exactly the reason for all the smart pointers 😬
@leonardodosanjoschaves620415 күн бұрын
I am just about to develop a “tree container”. The video content is so useful as an overview, clear, straight and didactic. Thanks
@CodeForYourself14 күн бұрын
@@leonardodosanjoschaves6204 awesome! Glad to hear it was useful and good luck!
@leonardodosanjoschaves620415 күн бұрын
I am enjoying so much this course playlist. Thanks!!!
@CodeForYourself14 күн бұрын
@@leonardodosanjoschaves6204 happy to hear that! 🙏
@JoseRomagueraM16 күн бұрын
It's great that people got interested by memory management, but I fully disagree with the usage of smart pointers and garbage collectors as a reliable and performant way of managing memory. Those techniques assumes that every "object" has his own lifetime, witch is fundamentally false: When there's one, there's many. This affects performance because of memory fragmentation and loses capabilities. I highly recommend the talk of Ryan Fleury about Arena Allocators, it's mindblowing how simple and effective a linear allocator can be. I almost never think about memory management and have all the performance and reliability.
@CodeForYourself16 күн бұрын
Arena allocators definitely have their use! However, if we allocate a lot of objects we will quickly need to manage memory in complex ways. This lecture targets largely the default behavior for beginners. I believe that using the heap for allocations should be completely fine in most domains. Also, heap implementations benefit from years of optimization and as far as I know they basically use arena like allocations for small objects. That being said, if one really writes a safety critical application and cannot use heap memory at runtime then yeah, we’ll probably need to allocate stuff from an arena. Also, I don’t agree with putting garbage collection and smart pointers in the same row. They are very different mechanisms. Smart pointers are definitely reliable and in case of a unique pointer have nearly no overhead. So if one wants to allocate on a heap, smart pointers are definitely a way to go.
@advik-b16 күн бұрын
This is quality content, your channel is underrated bro
@CodeForYourself16 күн бұрын
@@advik-b thanks for your kind words! Spread the word then. Let’s fix it. 😅
@div082616 күн бұрын
love this explanation
@CodeForYourself16 күн бұрын
Glad you liked it! 🙏
@bibekjha812917 күн бұрын
loving these videos.
@segfault456817 күн бұрын
Very Nice lecture, all my years I have always been a Composition over Inheritance supporter as well I knew that private inheritance can get the job done but never bothered to see how; example at 9:59 cleared the syntax and semantics up perfectly. ☺
@CodeForYourself17 күн бұрын
Glad it was helpful! 🙏
@pragyandahal735717 күн бұрын
Amazing content Igor, keep up the good work.
@CodeForYourself17 күн бұрын
Thanks! I’ll try my best 👌
@SanjeevKumar-nm7ps18 күн бұрын
you always deliver a masterpiece related to C++. Thank you so much for sharing your knowledge :)
@CodeForYourself18 күн бұрын
@@SanjeevKumar-nm7ps thanks so much for your kind words! You make me blush! ☺️ Glad that it is useful to you! 🙏
@glaubercini19 күн бұрын
Great video, however I couldn't figure it out how you change your T-Shirt that fast 😄.
@CodeForYourself19 күн бұрын
Oh, that’s very easy. You just mess up in the script, spend a week editing, then see that it’s wrong and that you have to re-record parts. 😅
@jojify19 күн бұрын
Great. Do you have any udemy course in detail for c++. I would like to purchase it
@CodeForYourself19 күн бұрын
Not yet, but maybe some day once I finish a full course here.
@politejellydragon899019 күн бұрын
Nah man, RAII is there for a reason. There is no free lunch. It's an indirection that in many cases isn't necessary. Writing a quick free with a null check into a destructor is not hard. Smart pointers are great for some things, but a shared pointer is inefficient and a unique pointer is kind of obsolete in many cases. I think nuance would make this a bit better. They should not be your default move. You should always evaluate your options.
@CodeForYourself19 күн бұрын
Could you elaborate a bit on how unique_prt is obsolete? This is the first time I hear about it.
@segfault456814 күн бұрын
How is Unique pointer obsolete? it executes the same instructions as Raw pointer, same size as well, Scott Myers even recommended them to be used in tight cycles. Shared pointer though not to be confused with Auto GC is still a deterministic destructor so plenty useful, the only inefficient thing I can recall about Shared pointer is that it is twice the size because of control block pointer.
@CodeForYourself14 күн бұрын
@@segfault4568 I have a similar view (thus my original question to the OP). As for the shared pointer the reference count is atomic if I remember correctly, which requires synchronization and therefore might cost additional resources and instructions.
@tirthasg19 күн бұрын
Nice explanation! By the way, what font-style, and colour-theme are you using? It looks pleasant to the eye!
@CodeForYourself19 күн бұрын
Thanks! The font is Fira Code. The theme that you see in the animations is a custom one that more or less resembles the default vscode one.
@tirthasg18 күн бұрын
@@CodeForYourself Thanks!
@CodeForYourself18 күн бұрын
@@tirthasg sure, anytime!
@alifimtiaj520619 күн бұрын
Great explanation. Liked and subbed buddy
@CodeForYourself19 күн бұрын
Thanks so much! 🙏
@kompila20 күн бұрын
How can I not like this video. Thank you Igor.~
@CodeForYourself19 күн бұрын
Thank you so much! 😊
@cozycactus28 күн бұрын
what fonts you use in terminal? i liked them
@CodeForYourself28 күн бұрын
I’m not entirely sure which one I used back then but I have mostly converged on using Fira Code everywhere now.
@bsdoobyАй бұрын
I like your (semantic) separation of impl.. inheritance and polymorphic inheritance 🎉
@CodeForYourselfАй бұрын
@@bsdooby thanks! I think it makes sense to teach them as separate concepts altogether
@alexanderbolinsky6430Ай бұрын
Fantastic explanations and visuals!
@CodeForYourselfАй бұрын
Thanks a lot for the compliments! 😌
@Pedro-jj7gpАй бұрын
Nice video! Why is the int* 8 bytes instead of 4 at 1:30?
@CodeForYourselfАй бұрын
@@Pedro-jj7gp that’s just the way it usually is on most modern systems: any pointer is 8 bytes. In the end this has to do with being able to address enough places in the memory if this makes any sense. That being said, other systems could theoretically have it be smaller or larger. Does this answer your question?
@Pedro-jj7gpАй бұрын
@@CodeForYourself It does, but I'm a bit confused as I was watching some other videos about vtables and they showed the vpointer taking up 4 bytes... I guess it could just be on that system.
@CodeForYourselfАй бұрын
@@Pedro-jj7gp it might be. But you can always check it on your system too. I’ve only ever seen 8-byte pointers on every system apart from really non-standard embedded boards. 🤷♂️
@Pedro-jj7gpАй бұрын
@@CodeForYourself Yup, you're right! I just checked using sizeof() both for a regular int* and a vpointer using reinterpret_cast<int*>() and both are 8 bytes. The video in question was 12 years old, maybe it was a 32-bit machine
@CodeForYourselfАй бұрын
@@Pedro-jj7gp sounds like a 32 bit system indeed. Glad that it makes sense now 👌
@SystemSigma_Ай бұрын
Nice and clean overview. However, dynamic polymorphism is a very well known and old topic in C++. I would suggest deepening into static polymorphism for the next video. Keep it up, it is refreshing to see technical C++ stuff in KZbin 2024
@CodeForYourselfАй бұрын
@@SystemSigma_ thanks! I actually put static polymorphism before this video, it’s right along a series of videos about templates: kzbin.info/www/bejne/Z37VpWSEgph-pKs Still not the most modern thing but necessary to understand concepts down the line I believe. I also wanted to give an overview eventually of how to do the same things using both dynamic and static polymorphism on some concrete examples. But for that people need to be familiar with both. Does this make any sense?
@SystemSigma_Ай бұрын
@@CodeForYourself It does indeed. I meant that modern c++ features (especially type traits) are really useful for making more robust static polymorphic code. Maybe instead of going too generic with topics, restricting the features scope may be more interesting for experienced viewers.
@CodeForYourselfАй бұрын
@@SystemSigma_ I agree that a more in-depth look would suit experienced folk better. My aim here, however, is to fill in the complete playlist that would tailor to somebody who knows nothing about C++ and guides them gently through all the main topics, providing the "why" for using what they learn along with enough information to dig deeper. Please see here for the full list to date: github.com/cpp-for-yourself/lectures-and-homeworks Maybe one day, I will finish the basic course and have some time to dig more in-depth into certain things. That being said, I feel that there is plenty of that type of content on KZbin already, while the comprehensive courses that I've seen all fell a bit short of what I wanted to achieve here. But we'll see if my course is going to be helpful to anybody 😅
@CodeForYourselfАй бұрын
@@SystemSigma_ oh, and just in case you have not seen already, I _do_ talk about type traits a bit more in-depth here: kzbin.info/www/bejne/f4KZY6d3apaJl8k
@danielstrombergАй бұрын
Hi. I think I have the C++ part of this completed, and would like to submit it for testing. But I'm a bit lost on the git side of this. I tried to use the same git template instance, and put my fortune_celler.cpp in ~/src/Full-C++17-course/t/cpp-for-yourself/homeworks/fortune_teller/task in a fresh branch (I also tried it in the same branch), but upon push'ing that to origin, I just got the example_homework graded again. Any suggestions?
@McDonaldIbekweАй бұрын
Thanks for the video. Please, can you focus more on Modern C++. Here are some: 1. Coroutine 2. Multithreading/Concurrency 3. Testing
@CodeForYourselfАй бұрын
@@McDonaldIbekwe ok, so there is one video on testing that I did before but it is not in-depth. As for coroutines I would have to use them in some real projects to be able to speak confidently about best practices that relate to them unfortunately. 🤷♂️ I will try to squeeze some multithreading in though at some point but I can’t say when just now 🤷♂️
@bsdoobyАй бұрын
structs do not need "public" inheritance; structs are public by default (sorry for being a PITA); you spare a few keystrokes ;)
@CodeForYourselfАй бұрын
Yes, you are totally right, but I much prefer to be explicit rather than implicit. My logic is that it is not a big deal to type one more word but it allows us to not think about which inheritance is going to be picked by the compiler implicitly should we omit that “public”. Does this logic make sense?
@zunobyАй бұрын
Чудова лекція. В майбутньому було б цікаво почути щось на тему concurrency, threads загалом.
@CodeForYourselfАй бұрын
Дякую! Радий, що сподобалось! Подивимось, взагалі план був про це розказати, але це така велика тема і в ній так багато чого відбувається, що я не впевнений що зможу її просто і добре пояснити. Але вона у мене в планах. 👍
@bsdoobyАй бұрын
nitpicking: if you use UML for you examples, the impl. arrow (realization of an interface) has a non-filled arrow head.
@CodeForYourselfАй бұрын
Yeah, I thought of fitting to the standard UML style but then left it at that considering that the tools I used for creating the visuals did not have a non-filled arrow 😅
@falol13Ай бұрын
SPOILER: Wrapping everything up with the Image class example from the start was a very nice move 👍 I really enjoyed this lecture and will definitely recommend this further. Thanks a lot for your awesome content! 👏
@CodeForYourselfАй бұрын
Thanks! I’m really happy that that move clicked. It was a long video so I wanted to end at one consistent example that would be relatively close to real life. 🙏
@AzerAnimationsАй бұрын
Haven't watched this yet, but I know it is good! One of the best C++ creators out there for sure!
@CodeForYourselfАй бұрын
Thanks for your support and such a trust in me 🙏 But feel free to revise once watched 😉
@bsdoobyАй бұрын
true words
@CodeForYourselfАй бұрын
This video took A LOT of time to make. Just the script I had to rewrite like 3 times. So, if you like what you see, please share this video with your C++ inclined friends if you found this video useful. 🙏 And do leave a comment, this way this video will be shown to more people apparently 🤷😉
@GeorgiosMATZARAPISАй бұрын
Pure joy. Thanks!
@CodeForYourselfАй бұрын
@@GeorgiosMATZARAPIS thanks man 🙌
@akshaypratap41232 ай бұрын
You have a very friendly face 🌞. I imagine it would be difficult for you to intimidate someone or to scold children
@CodeForYourself2 ай бұрын
@@akshaypratap4123 that’s not how I think I am usually perceived at all. Especially when I’m coding. 😅
@rishiniranjan17462 ай бұрын
Could use dockerfile also to preinstall all gtest/grpc libs
@rishiniranjan17462 ай бұрын
Best explanation ever found for cmake
@CodeForYourself2 ай бұрын
@@rishiniranjan1746 thanks! This means so much to me! 🙌
@BISONBOT942 ай бұрын
I am new to C++ templates and ran into this exact issue about an hour ago. This video helped me a lot, thanks!
@CodeForYourself2 ай бұрын
@@BISONBOT94 awesome! Glad I could help out! 🙏
@UvUtkarsh2 ай бұрын
I wonder how the templates are used in data structures in STL (for ex: vector) so that it not only works with primitive data types like int, float,etc. (for which can do the template specialization) but also with user defined classes/structs, which is not known before hand. Any ideas ? @CodeForYourself
@CodeForYourself2 ай бұрын
@@UvUtkarsh generally the code is written in such a way that as long as the provided types follow some form of an interface they should work. They also use traits and partially specialize classes based on what those traits tell about the provided type. I might do an in-depth look into this later if there is interest
@isfandyar39372 ай бұрын
what would you do with template class
@CodeForYourself2 ай бұрын
There is an example of this towards the end of the video. Does that answer your question? Or should I give a better example? How can I make it better?
@CodeForYourself2 ай бұрын
@@isfandyar3937 also, I cover this extensively in this video: Why use templates in modern C++ kzbin.info/www/bejne/Z37VpWSEgph-pKs
@xavierfrazao14692 ай бұрын
Great explanation. Thank you
@CodeForYourself2 ай бұрын
Glad you liked it! 🙏
@SystemSigma_2 ай бұрын
If I'm not mistaken, this only helps speeding up compilation times due to the explicit template specialisation. Still, what other benefits do I get by splitting template declarations and definitions?
@CodeForYourself2 ай бұрын
I guess you're right to a degree but there is more to it. Explicit template instantiation (different from specialization) does indeed help the compile times. It helps because without it, the code would live in header files and so would be copied to any translation unit that includes that header, leading to the compiler needing to compile all of those instances on their own. If we put the code into a source file (and for that we need an explicit template instantiation) we will only compile the code once and link it to the places where it is used instead. Does this make any sense? Now as to other benefits, one big downside of header-only libraries, apart from compilation times, is that all the implementation actually lives within the header files. Meaning that if we want to distribute our library to other people we essentially have to distribute source code. So in the end, we have a sort of a tradeoff, header-only libraries are quite simple to use but might lead to long compile times as well as to needing to show our source code to anybody using our library. I talk about this at length in the video about libraries here: kzbin.info/www/bejne/gqnSaZmqnNGqjqcsi=JYNvd_2i6GLjfdvv
@SystemSigma_2 ай бұрын
I'm perfectly aware of the standard benefits of splitting declaration and definition.. Still, for templates I really don't think it's worth the typing effort (if you're outside a smart ide) 😅 I guess the most valid point is only hiding the source code for distribution 😊
@CodeForYourself2 ай бұрын
@SystemSigma_ sometimes the compile times are important too. Some years ago I added a couple of explicit instantiations in a code base to save about an hour compile time 😅 I think if we *know* the types we’re about to use, then I would go for a compiled library as opposed to a header only one. It works also as an additional check for my design to a degree 🤷♂️
@SystemSigma_2 ай бұрын
@CodeForYourself yeah, I used it with quite a success in a few embedded projects, but, of course, every project is different so 🥲
@CodeForYourself2 ай бұрын
@@SystemSigma_ yeah, I agree. 🙂↕️
@CodeForYourself2 ай бұрын
Thanks a lot for watching, folks! Don't forget to share any thoughts you might have on this (or anything else)! 🙏
@yousefsaddeek3 ай бұрын
CMake Deez nuts
@Maximus982453 ай бұрын
Great video! One thing that bothered me a bit was usage of "<typename ClassT> to specify template parameter. The parameter has nothing to do with class, it could be just as easily called <typename T>, the word "class" gives a wrong impression, at least to me. Thanks!
@CodeForYourself3 ай бұрын
Ok, I agree with you that ClassT doesn’t hit the mark. What I prefer doing generally (when I cannot use concepts) is to give the template parameters meaningful names. Considering that this function is very illustrative and doesn’t really have a proper purpose it is hard to pick such a template parameter name, meaning the one that actually makes sense. So here I picked the ClassT as a substitute but I agree that it is a bit stupid and if I would have thought longer about it I probably would have just used T here. Thanks for your comment!
@PixelThornАй бұрын
For the win, my man
@francescobenacci66113 ай бұрын
@10:57 when we call DoSmth(number) i didn't expect the parameter type to be int&. Why is that, and not simply int? After all, it will be copied...
@CodeForYourself3 ай бұрын
Unfortunately the answer to this comment is more complicated than I would like it to be. It has to do with how overload resolution is taken care of in C++, which is not trivial: en.cppreference.com/w/cpp/language/overload_resolution But the rule of thumb, at least the way I think about it, is that if we have a local object the compiler will prefer passing it by reference if an appropriate function overload exists. During this some implicit conversions can take place as well as some copies performed. My recommendation would be to write a simple example with some Foo function that has various overloads and see what the compiler does in each case to build more intuition. That being said if somebody who can explain it better stumbles upon this comment, I would like to find a nice and simple explanation for the future. 😅
@francescobenacci66113 ай бұрын
@@CodeForYourself thank you, i really appreciate the answer, it surely provides a good starting point for me to try and understand this :) Keep up the great work, i discovered your channel with this video, and decided to start the whole course from the first lesson, even if I'm familiar with some of the basics of C++
@CodeForYourself3 ай бұрын
@@francescobenacci6611 thanks for the kind words! Please mind that the first videos have a slightly different style from this one. I guess I converged to a style like this some time around the cmake video 😅
@segfault45683 ай бұрын
Universal Reference gang member Here, Scott Myers most loyal soldier.
@CodeForYourself3 ай бұрын
Welcome 😅
@zamf3 ай бұрын
An interesting fact is that forwarding (or universal) references were discovered and not designed in the language. They just happened to spring into existence following the rules of template deduction and reference collapsing. It's one of the many miracles of the language showing that when you design something right it gives more value than designer has originally anticipated. It's an example of 1+1 giving more than 2.
@CodeForYourself3 ай бұрын
Yes, thanks for this comment! I believe the reason the name “universal reference” exists is just for that reason too! It came before the “forwarding reference” name was used in the standard. That being said, I don’t have the hard facts for this, so if somebody can point me in the right direction I would be immensely grateful 😉