Learning C++ in 2010
I'm currently learning C++ for a project I'm working on. However, I do have a problem. The huge amount of (possibly incorrect) information Google returns leaves me a bit confused sometimes. Like PHP and many other languages, there's obviously a lot of bad code out there.
So I'm wondering what are the best resources for learning C++ in 2010? Has the best practices for C++ changed much in the last 10 years? The most valuable resource I have found so far is the Accelerated C++ book, is it still relevant?
53 comments
[ 3.6 ms ] story [ 102 ms ] threadWhich "is 500% larger than the C++ FAQ Lite." Invaluable.
I've worked with some people who used Google as a C++ reference, but they'd often write code with subtle problems because some random blog or reference isn't a good way to build a solid understanding. I'd suggest going straight to the source: the standard (it's not that complicated), your compiler's documentation, and Guru of the Week: http://www.gotw.ca/gotw/
Then read Effective C++, More Effective C++, and Effective STL by Scott Meyers. Then move on to Exceptional C++, More Exceptional C++, and and Exceptional C++ Style by Herb Sutter.
Stay away from Alexandrescu's books. Template meta-programming and "modern C++" is very powerful but will only end in tears. It's great to know this stuff but probably shouldn't be used in production code that you actually want to ship.
That said, the Effective * books are great.
Before then, my justification was that C presented a cleaner environment than C++ to some of the core concepts, like pointers not being cluttered by having to know about references or the `new` operator. But things like that pale in comparison to the overall style of program design between the languages, which I think is far more important.
How dare you simply tell a newbie C++ programmer "Template meta-programming and 'modern C++' ... will only end in tears" without providing a rationale or at least the details of whatever bad experience you had with it. The world has enough cargo cult programmers and enough people who do convoluted things to avoid using some language feature that they believe is "bad" without really knowing why they think it is bad.
Illustrating the best reason why you should NOT learn C before C++...
Great C++ looks like code written in Meyer's and Sutter's books.
I suggested TCPL because C++ is one huge mishmash of features. TCPL teaches you the basics of function calls, loops, conditionals, memory management, pointers, etc. The Meyers & Sutter books help you write great classes and code that is exception safe, and generic, etc.
All of the other books about C++ I just can't recommend for learning.
It's a community dedicated to C and C++.
It has great tutorials, references and an amazing forum.
http://www.cprogramming.com/tutorial.html
http://www.cprogramming.com/board.html
I thought I knew C++ well, but the book Modern C++ Design by Andrei Alexandrescu completely blew my mind. It's a bit advanced, and more of a cookbook than in introduction, but it does serve to introduce some of the more recent innovations in C++ programming.
And of course don't forget stackoverflow.com. Heck, I think I saw this exact question (good C++ programming books) was a top question a couple months ago.
Feel free to look through Stack Overflow's C++ tag (http://stackoverflow.com/questions/tagged/c%2b%2b) to get a flavor of this, many C++ questions have a Boost answer.
Here are my tips for you. First tip: Don't trust any C++ code that anyone else writes. This is related to Meyers' tip that C++ is a "federation" of languages. As you have noticed, there is a lot of bad code. But even good code can have bad consequences. C++ is extremely idiosyncratic and the author will make assumptions that you will follow certain practices (deemed as "the right way to program in C++") which will vary from author to author. You may even start to notice this in the comments. Corollary: Only trust a library if it's very well documented and frequently used. Boost may be worth a look, and lots of people like it, but I can't promise that it works.
Second tip: avoid reference counting "smart pointers" whenever possible. This directly contradicts Scott Meyers. Instead, use valgrind to make sure your program doesn't leak memory. If your program is infeasible to write without automatic memory management, switch to a language such as Java or C# which is built atop a robust garbage collector.
Third tip: view C++ as a bit like an extremely sharp knife. Easy to get things done, even easier to cut your finger off. Just because an example looks slick and easy does not mean that using it in practice is slick and easy.
As for my rationale, reference counting is by most accounts an obsolete form of garbage collection. The smaller your object is, the more space you waste. If your references are at all cyclic, you have to introduce weak references, in which case you must understand your memory structure to the point where you should be able to manage your memory without garbage collection. (Languages such as Java contain weak references, but are never needed and only should be used for things that the programmer is willing to lose such as a cache.) Cyclic references will creep up on you when you least expect it.
Using valgrind IN ADDITION is a good idea, but there is no reason to avoid smart pointer memory management.
You cannot use valgrind to "make sure your program doesn't leak memory." You can only use valgrind to find SOME memory leaks. Particularly for a long-running process (e.g. a daemon), there could be a memory leak that doesn't show up in valgrind unless you run it for 3 weeks. Or what if the daemon only leaks memory on Thursdays, but you test your program under valgrind on Mondays?
I'm not saying that valgrind isn't useful -- it is. But it is NOT a good idea to rely solely on valgrind to find your memory leaks. A much better idea would be to use other techniques (e.g. smart pointers) to avoid memory leaks in the first place, and then to use valgrind on top of that.
For further questions, refer to the C++ Frequently Questioned Answers.
And the subset argument, although it has some truth in it, is misused a lot. Sure, I do not use all of the C++ features, but how can you choose a subset well if you do not have at least an idea of most features? And the well-chosen subset can be different from project to project. I see C++ in a similar way to a large toolset (I mean a metal/plastic/wood toolset, not a software toolset). You don't need to master all the tools in a toolset to do a particular job, but you should have an idea of most of them.
I agree that the metaprogramming stuff in C++ is not something for beginners.
Or even for most programming problems, in general!
Templates should be used when you are writing a container class. That's about it. Using them for crazy hard-to-read and hard-to-debug metaprogramming purposes is just irresponsible.
Alexandrescu and Stroustrup's books will teach you a lot and open you to what is possible in this amazing language.
Weather you will use those techniques in your project however, depends on the project, your team, your clients, etc.
It is a free resource, and gives you the whys and hows on most aspects of c++. Buy the book when you decide that you like it, I did. It is especially good if you have some prior experience to programming, like java or C
And boost is almost an extention to the std libraries, so get to know them, those are tomorrows standards.
I recommend it because it illustrates important concepts in Computer Science while avoiding the unnecessary idiosyncrasies of C++. I like to think of it as a Coles Notes version of CS essentials but the material might be a little too basic for an experienced programmer.
http://bit.ly/bTMjtd
I've found the best practices for C++ are usually to practice avoiding best practices whenever possible. That is if you're in it for the olde 10-year Norvig cycle.
Time allowing, bottom-up programming (as the equally venerable On Lisp details) also applies to design patterns, template meta-programming and all that. It's good to read about them, to learn what others have experimented with and found to be useful (or so they think). But you're only really going to learn them in the context of something useful and practical. It's much better to discover them for yourself in practice.
That said, there's a lot of C++ syntax and STL idioms that are not obvious at all -- which make Meyers' books very important (particularly the first one) even for starting out.
Also, C++ as doctrine is not fun -- i.e., a way of 'thinking' about programming. But C++ as a collection of language-changing extensions to C is not so terrible. I guess that's true for anything.
Actually, now that I think about it. There's Lisp and C -- elegant, simple languages on top of assembly and the lambda calculus if you wish or FP if that's what you emphasize (i.e., math). These are in fairly close approximation to code (assembly) that is in fairly close approximation to how hardware or math works. These provide structure on top of that.
And the rest, whether OO in Java and C++ and its rough attempt to merge type theory with performance-consciousness of the actor model from Simula and Smalltalk and Objective-C and all that -- the rest are just organizing paradigms on top.
It's late. I've been coding all night. I forget what the question is. There's like 10 dimensions in play when you learn a new language. But like anything, if you're in it for the long term, whatever you learn, learn it really well. There's a lot of similarities at all levels.
tl;dr Read SICP.
http://www.cplusplus.com/reference/
It has great reference for the C++ and C standard libraries. The best thing is that there are simple but _very_ good code examples accompanying each function description showing how to use it in context. Can't recommend this reference highly enough.
http://www.mindview.net/Books/TICPP/ThinkingInCPP2e.html
I remember back in college I used to refer to one of his books (can't remember which, I'm afraid) and it was pretty well written
Seriously. I am a C++ expert (10 years and counting) and I've never read a single book on C++ in my life. Just keep programming and keep asking questions until you get answers.
Ignore fads / popular opinion if you think you know a way of coding something in a simpler, cleaner way than what most people think you should be doing for some silly pedantic reason. (If they have a point, then use their technique of course -- but if it's like "All objects should be declared as noncopyable!" then ignore it. 99% of the time, objects should be considered not-safe-to-copy, so there's no reason to bloat the code by declaring objects as noncopyable. That type of thing.)
Also, AND I KNOW I'M GOING TO GET FLAMED FOR THIS, try to avoid using Boost unless you're doing multithreading. Just because you can use smart pointers, doesn't mean you need to use them everywhere and just because you feel like you "should be". Boost seriously bloats the code (compilation times shoot way up, and there is runtime overhead as well, not to mention that if you want to send your code to someone then they need to have Boost installed to even compile it). I don't use smart pointers at all, and my code doesn't crash or have memory leaks. It's not hard to write a manager class that allocates a type of object and adds it to an internal list, then de-allocates all of the objects when the manager destructs.
Write a program in the simplest possible way you can think of to get it working correctly. Then re-write your code entirely, so that it's more readable and cleaner (and commented). Format the code using tabs / whitespace so that the code is even more readable. Then re-write it again, this time simplifying the code even further. Now you have clean, well-written C++ code.
Effective STL is probably the single most valuable C++ book out there. A decent but superficial grasp of C++ plus Effective STL will get you a long, long way in actual coding.
Every C++ dev should have Stroustrop on their desk.
If you're just coming to C++, Alexandrescu will just confuse you.
Watch out for Boost, the most popular C++ add-on library. It's solid, but it's also confusing, and you don't need it for anything.
Soon I realized C++ is full of idioms that you need to be aware of most of them to be really good-- which basically meant you know exactly what you're asking the compiler to do. For that, I have used Effective C++ (don't forget -Weffc++ flag in GCC), Exceptional C++, Effective STL, The C++ Standard LIbrary (Josuttis) as reference and reading. They have helped a lot.
Now, I look into boost source tree once in a while to see how they do certain things or to debug some boost libraries. Nowadays that's where most of my learning comes from.
"In C++ it's harder to shoot yourself in the foot, but when you do, you blow off your whole leg." — Bjarne Stroustrup
Stroustrup's The Design and Evolution of C++ (http://www.amazon.com/Design-Evolution-C-Bjarne-Stroustrup/d...) is very good for explaining the "why" of C++, especially the stranger parts.
One other note, echoing some of the others: everyone picks out a subset of C++ and programs in that, and smart companies make that formal. You might see if your problem domain matches one of the available good ones, like Google's (well, I've heard that it's good).