Modern C++: Unique Ptrs and Vectors

preview_player
Показать описание
Dave takes you on a tour of the modern C++ features you need to know in order to avoid memory leaks, corruption, and other common pitfalls of using C++.

Рекомендации по теме
Комментарии
Автор

More videos like this, please. I'd like to learn C++ but all these libraries and concepts required to understand how to use it properly are doing my head in. This video really helps clear things up.

CristiNeagu
Автор

I learned more in this 16 minute and 24 second video than I did in an entire month of drag and drop “programming” that they tried to teach in school. Thanks for making these videos and explaining everything in a way that’s easy to understand.

bdp-racing
Автор

That is such a great and straightforward example of the use for unique_ptr. Your epic mastery and years of experience shine through in how clean and clear everything is.

systemloc
Автор

Hi Dave, as someone with far too many years of embedded C experience, but only a couple of years of self taught C++ I'm still sort of in the wrapped C category. Though I do like and use Vectors wherever possible.

If you are ever stuck for video ideas, then a C to modern C++ conversion course would be fantastic.

Thank you for the constant stream of interesting and high quality videos.

nicholasdark
Автор

As someone who had modern C++ drilled into him by a person many years his junior, I appreciate this series for giving me the mirror opposite experience 😆 One very small nitpick, though: if you look at vector's implementation of push_back with an r-value reference, it actually just calls emplace_back using move semantics. I've found it a good habit to explicitly call emplace_back when your intention is to move an r-value reference into a vector!

snobaste
Автор

You can also put "using" at the top of any scope, for instance a single function in which you expect to type std:: a lot. Sort of a compromise between convenience and risk reduction.

delsorou
Автор

I love your holistic approach, instead of teaching just the concept, you ensure the viewer can digest the information(like how you dealt with std::vector's poor naming)

k_gold
Автор

Sir, you should now really start considering teaching here on YouTube. The explanations are one of the best ones we can get out there and especially when it comes from someone who has decades of experience in it. Full scale courses coming from you would definitely help us learn in the best way possible and will also make people fall in love with programming.

poushankumarbiswas
Автор

Amazing video. At my university, so far we've been basically taught "C with Classes" as you mentioned in the video. I have had some assignments involving Vectors but as I've already used ArrayLists in Java so it's nothing new to me. I have came across the new pointer types in modern C++ and read a bit on them, but this video made them very easy to understand and I really appreciate it!

Sonavyon
Автор

std::vector<>.shrink_to_fit() is also one of the most underrated functions that exists if you know you are not going to expand it at once, or for not a long time.

scienceandmathHandle
Автор

Very interesting. I am a very old programmer. But not on UNIX or Windows, but "legacy" IBM z series hardware, back to S/370 days. I was introduced to C/C++ back in K&R times, on Windows 95. Nice to see the C/C++ language continuing to advance.

johnmckown
Автор

Excellent working example. Your coding style is extremely efficient and easily understood.

rickpoeling
Автор

I think this video has very good intentions, but it has some issues that I would like to point out:

7:45 Avoid using plain enums in new code. Prefer enum class which declare separate types instead of declaring the equivalent of global variables of type int. With regular enums ACE == DIAMONDS produces true whereas with enum class Rank::ACE == Suit::DIAMONDS is a compiler error. (see C++ Core Guideline - Enum.3 Prefer class enums over “plain” enums)

9:01 Although this example tries to illustrate the use of unique_ptr, this is a perfect example of when not to use it. Remember, a vector already puts it's storage in the heap, and already manages it's memory allocations and deallocations automatically.

Aditionally, Card objects in this example are really small, so you really are better off passing them by value than by pointer anyway (easier to code, and better performance). But that misses the point of the example. I'm guessing that the idea is to imagine that Card objects are expensive to copy around. I just wanted to mention this, for anyone interested in applying this in real-world programs.

9:18 This is right, but the vector will call the destructor of the elements in a loop. For unique_ptrs this is really slow because you're deallocating a bunch of objects one by one. For Card objects the destructor actually does nothing and the compiler optimizes this loop away. Then the whole memory of the underlying array is deallocated in one go (in both cases).

9:44 There is no need to specify upfront the size, but in most cases you either know the size, or a decent estimate, which is good enough (in this case we know the exact size: 13*4). This is good to avoid "distributed fat". You can get a better explanation in this talk that you can find here in YouTube: `CppCon 2014: Chandler Carruth "Efficiency with Algorithms, Performance with Data Structures"` around 21:28

10:53 You actually CAN have multiple pointer references to whatever a unique_ptr points to. They are just non-owning references. You do this by getting a raw pointer from the unique_ptr using the get() method.

Contray to popular belief, raw pointers are actually fine in modern C++, you just have to avoid using them for memory management. You accomplish this by never calling new and delete manually. Other than that, raw pointers are just fine. (see C++ Core Guideline - R.3: A raw pointer (a T*) is non-owning).

11:43 You might want to make the random device and the random engine objects static. Just to avoid constructing them every time that you call shuffledeck. Construction of these objects is fairly expensive, and just adding static does the trick for simple cases. For a thorough explanation, see the talk `CppCon 2016: Walter E. Brown “What C++ Programmers Need to Know about Header <random>"`

12:55 std::move is pretty counter-intuitive and actually just does a type-cast. It might or might not trigger a move by changing the type, depending on the context where you call it. I think in this case we're not changing the type at all (the call to std::move does nothing, and can be removed), but the move still happens. Additionally, since the move happens, the unique_ptr in the vector is left in a moved-from state. But it is fine in the end though, because he does the pop_back right away, removing the moved-from object.

The explanation saying that it would be fine even if left in the vector is wrong. It is undefined behavior (UB) to do anything other than detroying an object in a moved-from state. So if it was left in the vector, a sub-sequent drawCard() could draw that same card and then any operation on that drawn card would be UB (including the possibility of corrupting memory, though most likely you'll just segfault).

More explanation in the C++ Core Guideline - ES.56: Write std::move() only when you need to explicitly move an object to another scope. For a thorough explanation, this is the talk: `Back to Basics: Move Semantics - David Olsen - CppCon 2020`.

14:01 You're indeed never duplicating cards. But even if you use value semantics (aka. a vector<Card> instead of a vector<unique_ptr<Card>> ), which would involve copying card objects, you are still avoiding all of the pitfalls of manual memory management.

kebien
Автор

I'd really like to see a follow-up to this that would show how a "C with Classes" style would write thw same program. I'm guessing it would simply replace the vector with an array, and the unique pointers with regular pointers, but it would be nice to go over exactly where the memory and aafety issues can arise.

Also, I really hope you do a Rust video. The safety and performance of Rust is amazing, but it's actually the developer ergonomics and the ease in importing and project orchestration that makes me dread touching the C++ project I have to maintain.

zactron
Автор

Excellent video, Dave! I'm retired now, but I had been programming in C++ since 1991. The STL is a wonderful thing indeed! Thanks for your channel!

KeithCooper-Albuquerque
Автор

More videos like this please Dave, you are a great teacher and I always learn something from you. Thank you for all your hard work. John, Ireland 🇮🇪

SassyToll
Автор

Since the video is about "modern" C++, a couple of code-review pointers..
1) Line 9-15: You should use "enum class" instead of "enum". The former (available from C++11) will avoid name-collisions.
2) Line 86: You don't need to insert a space between two ">"s like "> >". You can just write ">>" since C++11.

rdman
Автор

I took a long journey away from C++ and haven't looked back, but this gets me interested in poking around once again. Thanks Dave.

disruptive_innovator
Автор

Just as a note for those that use the Qt framework.... you can use the QScopedPointer and QSharedPointer classes instead of the std unique and shared points repsectively. Also Qt provides the QVector class to handle vector operations.

douglascaskey
Автор

I've been really wanting to get back into C++. I diverted to C# back in a time where conventional wisdom told you to actually avoid the C++ standard libraries (a long, *long* time ago). But much like how C# isn't anything like it was when I first started learning it (remember when they championed verbosity?) c++ feels like a completely different beast now.

sirflimflam