Uncage Your Code with C++3/18/19
Are you tired of having your hand held by a garbage collector? Are you ready to have your code uncaged from the confines of its virtual machine? Are you ready to have your code run blazing fast, right on the metal? Do you want bragging points for knowing a language with a feature list longer than a CVS recipt? Then C++ is the language for you!
Who is this guide for?
This guide is for anybody who wants to learn C++ and has experience from a language with automatic memory management. Such languages include:
What does this guide cover?
This guide covers strategies for memory management as well as some C++ features that may not be present in other languages. The goal of this guide is to help newcomers write idiomatic C++ code and make good decisions with memory management.
What doesn't it cover?
The rest of the damn language. Go read a book by Stroustroup for that. He's got like four of em.
1. Use const, use it everywhere.
const is a lovely feature of C++ and you should use it as liberally as possible.
Firstly, if an object is declared as
const then you get a compiler-backed guarentee that this
object will never change. That means that your code will have one less moving part that can go wrong.
On top of that, the compiler can make optimizations around
objects that it wouldn't otherwise be able to make. Using
const means speedier and less error-prone code.
Const references are also worth mnentioning. Even if you have a non-const object, you can pass it to a function as
a const reference and get the above guarentees and benefits. Your object becomes
const for the duration
of the function and cannot be modified.
Finally non-static methods on objects can also be labeled const. You can run these methods and be sure that your object will stay unaffected.
Now isn't all of that lovely? In fact, using const is so beneficial that the official CPP Core Guidelines recommends that you use const by default! So remember, Use const, use it everywhere!
2. Auto is your friend
C++ is not exactly known for brevity. Between having to write "std::" for every single standard library function and typing out things like
might get sore before you've even written anything useful.
auto is here to save the day. Automatic type deduction means that your compiler will automatically figure out
the type of your declaration based on its assignment. Use
auto for grabbing elements from vectors.
auto for getting results from functions. Use
auto for foreach loops. In general, you can use
The typing of a field is obvious or unimportant.
3. Combine the two!
You will end up writing
const auto and
const auto& for a lot of fields for the above reasons.
To make life easier, I took a page out of rust and swift's book and created an IDE shortcut,
Whenever I type "let" and hit spacebar, CLion automatically changes "let" to "const auto". This made the verbosity of C++ far easier to deal with.
4. C++ lets you optimize like a madman. Don't do it.
C++ is already a blazing fast language compared to other VM languages. However, the amount of flexibility C++ offers means that there are countless ways to """improve""" your code by doing things like avoiding copying and doing things in less steps.
Don't do it! Computers are fast and C++ is even faster. Computer time is cheap but Your time is priceless. Don't spend half an hour writing optimized unreadable code that cuts down Performance by 5 milliseconds in an edge case. That time is better spent working on other features!
Chances are, you won't notice any slowdowns even when you don't optimize everything. Even if you do, you can easily go back and optimize once you've completed other tasks. Save that for later!
5. RAII: Resource acquisition is initialization
In C++, objects acquire resources such as heap allocated objects in their constructor. In their destructor, objects release these resources. This is how we manage the chaos of pointers and resources and avoid memory leaks. This is C++'s replacement for garbage collection. Like the Japanese, objects in C++ clean up after themselves!
6. ..which means you should avoid the new keyword outside of constructors
Creating an object with new is a liability. Like Kanye's water bottle you are now responsible for your object. You must remember to delete it at the appropriate time. You must remember not to use it after deletion. You must remember not to delete it twice. What a hassle!
The only times you should ever consider using the dreaded
new keyword is in the constructor of an object. The constructor can allocate an object with
new and a matching destructor can free that object's memory with
delete. This keeps your resources management tidy and worry-free!
Another acceptable use of
new would be when working with libraries that require it. Most of the time, these libraries will manage deletion for you once you pass it off into their care.
However, if you feel tempted to use new outside of these cases...
7. Use a smart pointer!
Smart pointers are great because they manage memory for you!
std::unique_ptr is what you want most of the time. It holds onto your pointer for you when you declare it. You can use it like a normal pointer while it's alive. When it goes out of scope, it automatically
deletes whatever it points to and frees the memory for you. In order to prevent double deletion, it cannot be copied. It can, however, be moved or returned from a function or passed to different scopes so long as you don't copy it.
std::shared_ptr is another type of smart pointer. It's is used when you DO want the ability to copy your smart pointer. When you create and copy a shared_ptr it knows exactly how many brethren it has. When all the shared_ptrs that point to a single object are deleted, the object self destructs. It is mainly used for multithreading and functional-style programming. Chances are, if you're reading this guide, you won't need to use it any time soon. But it exists and now you know!
8. A handy guide on how to pass data
This chart speaks for itself. Admittedly, I got this chart off some guy on discord and I'm not entirely sure if he made it either. In any case, now the chart is yours. Consult it whenever you want to figure out how to pass data in and out of a function.
The mount of choice that C++ offers is overwhelming. These tips and rules of thumb help mitigate that feeling of analysis paralysis so you can focus on actually programming instead of fighting the language.. I hope this guide can be a good starting point for your C++ journey.