The following is a list of materials I tend to suggest to people learning C++. It approximately follows my own path, can cater for those with some sort of programming experience, and may suit complete newbies. Most of the material is more about using C++ correctly, efficiently and safely, or code design, rather than a guide to the language itself, and makes good reading and re-reading for inexperienced and experienced developers alike.
Knowing the language and standard library facilities
The bulk of my early learning was the language itself, and the facilities provided by the standard library.
Thinking in C++ by Bruce Eckel is a highly-acclaimed book of 2 volumes that is available free online. This is a good place to start for beginners, and helped me really ‘get’ a few of the C++ concepts I found trickier early on.
The C++ Programming Language by Bjarne Stroustrup (the creator of C++) is a great, authoritative reference on the language, second only to the standard document itself, but is rather dry. I find it more useful as a reference than casual reading, but YMMV.
Marshall Cline’s C++ FAQ Lite was, I think, the first material I read that moved my learning from pure syntax & library up to the idiomatic level with the virtual constructor idiom. It’s been going for over 20 years now and has so far been updated frequently, however its content has now been subsumed into the official ISO C++ FAQ in combination with information from several other reputable and authoritative sources (Stroustrup, Sutter, Alexandrescu).
Danny Kalev sat on the C++ standards committee a while back, and has created a good C++ reference guide, which is more like a learning guide than a reference. It seems to be kept well updated, and though I haven’t really scratched the surface reading it, the bits I have read have been good quality. It also introduces some parts of the latest standard.
Most of the time cppreference.com is my first port-of-call for standard library questions, since it’s easy to navigate and has a sensible URL structure (e.g. /w/cpp/container/list/front). cplusplus.com can be good too, though has been less responsive to language updates and not of such high quality.
- Overview of C++11 string ↔ number conversion functions [codexpert.ro]
Levelling up your code quality, safety & design
Scott Meyers is a prominent figure in C++ circles, and his Effective C++ and More Effective C++ books give excellent, in-depth coverage of the practicalities and technicalities of using C++. I haven’t read Effective STL, but expect that it is equally good if you’ll be using those facilities. Both EffC++ and MEffC++ are must-reads for a professional C++ developer.
Herb Sutter’s Guru of the Week blog was a series of articles on aspects of OO design and under-the-bonnet/technical C++. I’d highly recommend it once you’re familiar with C++. He’s currently adding to that for C++11 features here, albeit at a measured pace. The slightly lengthier Sutter’s Mill articles listed here are also great material. Familiarising yourself with everything in GotW is a definite level-up in C++.
Robert C. Martin (“Uncle Bob”), has some good papers on principles of OO design. He’s also rather well-known and has other Good Stuff about software craftsmanship.
Making things easier (and safer)
The Boost C++ Libraries have some extremely useful facilities (both general and specialised), are free, actively developed, well-known and accepted in the C++ world to the point of ubiquity, and are excellently written. Some parts of it are of high enough quality and relevance to have been accepted into the standard library in Technical Report 1 [TR1] and C++11.
Three Five Zero?
Prior to C++11 the Rule of Three [Andrew Koenig, Barbaro Moo] existed to guide safe class design around destruction and copy operations. Then there was a period during which the Rule of Five ruled for C++11. Now that C++11 is better understood we have the Rule of Zero [R. Martinho Fernandes], which combines the safety of the previous rules with the Single Responsibility Principle (see Uncle Bob).
Juan Alday‘s article Enforcing the Rule of Zero [ACCU Overload #120] walks through the the difference in wording of the C++03, C++11 and C++14 standards regarding defaulting/deletion of copy/move constructors & assignment operators, the resultant behaviour, and what we should (or should not) put in our classes as a result.
Marco Arena followed up from Juan’s article with Ponder the use of unique_ptr to enforce the Rule of Zero, in which he looks at polymorphic deletion, which requires a virtual destructor, which prevents automatic generation of move and (possibly) copy operations, and how to sidestep that problem with a minimum of additional overhead.
The Boost website has an overview of generic programming techniques used in the libraries; although light on detail this is a good introduction for anyone new to this aspect of C++.
C++ Template Metaprogramming [Dave Abrahams and Alexey Gurtovoy] is an excellent and comprehensive coverage of the subject; I have yet to see a comparable collection of all the goodness this book contains.
In Exception Handling: A False Sense of Security, Tom Cargill illustrated the difficulty of writing exception-safe code through examination of a simple stack implementation. Although written in 1994 it remains relevant and enlightening. Sutter’s follow-up Exception-Safe Generic Containers makes the stack exception-safe in several different ways, and provides a lot of expertise that can be applied when considering exception handling in any code.
Dave Abrahams’ Exception-Safety in Generic Components introduces the concept of 3 levels of exception-safety guarantee (commonly known as the Abrahams guarantees) and shows his approach to specifying and testing exception-safety of the STL. Although short, this is well worth a read, particularly given that Abrahams was the driving force behind standardisation of the standard library’s exception-safety (and co-founder of Boost).
Lvalue, Rvalue and ‘Universal’ References
Rvalue references were a significant change to the language made in C++11, and added a whole new variety of ways to pass parameters, requiring new idioms be born, trialled, and inevitably some to die off. The community is still figuring this out; some of the articles below are key to this journey.
A good place for a neophyte to start is with Thomas Becker’s comprehensive introduction to Rvalue references.
Dave Abrahams wrote a well-known article Want Speed? Pass By Value [Wayback Machine copy], which Scott Meyers followed up much more recently with Should move only types ever be passed? There’s a good, lengthy discussion in the article comments that merits reading too.
The go-to text for a good grounding in this has to be Anthony Williams‘ excellent book C++ Concurrency in Action. Not only does it cover the primitives (threads, mutexes, condition variables, atomics, futures & promises etc…) and how to use them, but also how to design with them, and all using the facilities specified in the C++11 standard. He even dives into the nitty-gritty of ‘lock-free’ programming, and as if that weren’t already enough, Anthony had heavy involvement with the ISO C++ committee’s Concurrency Working Group in specifying many of these features based on his experience developing the just::thread library.
Jeff Preshing has written a few articles on lock-free programming that really helped me to get my head around it – I found Acquire and Release Fences particularly useful, but recommend checking out the others too.
Wait-free queueing and ultra-low latency logging piqued my interest as a neatly self-contained case study in, well, ultra-low latency logging.
Testing Culture by Mike Bland shows good reasons to include unit testing as part of a broader test strategy. (With emphasis either on ‘unit testing’ or ‘broader’, dependent on which bit you’re not already doing!) He uses the notorious OpenSSL “Heartbleed” bug as an example.
Martin Fowler‘s Mocks Aren’t Stubs is good as it not only [re-]establishes a common language we can use when referring to different types of test doubles, but provides the categorisation for us to be able to reason about them, and which are useful in different scenarios. He finishes with a look at two different approaches to mocking. (FWIW I follow the Mockist style.)
Ulrich Drepper’s (lengthy) document What every programmer should know about memory [pdf] is a comprehensive tutorial of memory and caches and much more. Great start if you’re writing high performance code.