Hacker News new | past | comments | ask | show | jobs | submit login
Learning C++ in 2010
38 points by martinp on Feb 12, 2010 | hide | past | favorite | 52 comments
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?



Effective C++ by Scott Meyers has some good tips.

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.


I disagree as fervently as possible; always use reference counting smart pointers. It is substantially harder to guarantee exception safety if you don't make use of them. You'll also be able to program more quickly without devoting extra mental cycles to make sure everything is cleaned up properly.

Using valgrind IN ADDITION is a good idea, but there is no reason to avoid smart pointer memory management.


The best way to deal with exceptions is to disable them. Arbitrary interruptions of control flow will screw up just about any algorithm. Otherwise, you will have to reason about everything using RAII semantics, which work well much of the time. Smart pointers have the same problem. You may believe that everything is cleaned up properly with your smart pointers, until a cyclic reference happens one day.


What is it that you don't like about smart pointers? Surely the small performance consequences of using something boost::shared_ptr are outweighed by the exception/leak safety that it provides 99% of the time.

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.


You are arguing for a solution which works "99% of the time" and then argue that my solution does not work for programs which only leak on Thursdays. Smart pointers won't fix all your memory leaks either due to cyclic references. Any program that runs for 3 weeks should be built to handle restarts, and have a failover architecture in place.


What is your rationale for tip #2? Don't forget that you also have to guard against other kinds of leaks: handles, database connections, etc. Given the lack of a finally clause in standard C++ try/catch blocks I'm not sure how you can do that successfully w/o smart pointers and their ilk.


Of course C++ has RAII, as you must know. Allocate the object on the stack or, if you must, use a stack-allocated auto_ptr if you want it to last as long as the block, as the destructors for stack-allocated objects form the hidden "finally" clause of every block. Otherwise, it is stored somewhere, and the object that stores it should manage it. If you store an object in many different places with no master location, you are starting to wander into automatic memory management territory.

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.


Nowadays, many people think Boost (http://www.boost.org/) when someone mentions C++.

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.


http://www.parashift.com/c++-faq-lite/ -- one of the best resources for c++, imho


Except for the book: http://www.parashift.com/c++-faq-lite/faq-book.html

Which "is 500% larger than the C++ FAQ Lite." Invaluable.


There's a somewhat recent reddit thread, fyi.

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.


Go to the IRC chatroom #gamedev on the server irc.afternet.org. Ask specific questions, and put up with people being frustrated by your lack of knowledge. You can quickly get the correct answer to almost any C++ question you can think of, but you have to put up with a lot of silly flaming / chest beating to get to the answer.

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.


Whatever you do, don't look at Bjarne Stroustrup's book, it's terrible. Ignore Andrei Alexandrescu, he tries to turn you into a template metaprogramming zombie. The way to go is to find a subset of C++ which works for you and stick to that.


To know which C++ subset to use on your project, you need first to learn a little about ALL C++.

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.


Stroustrup's "The C++ Programming Language" is one of those books which are always around my desk and I still would consider it as the best reference book on C++. I have not read his "Programming: Principles and Practice Using C++", but it is said to be targeted more at people learning C++.

I agree that the metaprogramming stuff in C++ is not something for beginners.


"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.


What you are saying is that he should not learn C++.


Well, that would be the optimal solution, but, since the author of the post is asking for it... learning a well-chosen subset seems to me the most adequate answer.

For further questions, refer to the C++ Frequently Questioned Answers.


C++ is large, and it is not perfect, but it is very good for a large set of diverse problems. I find pointless C++ bashing (such as the FQA) quite annoying, although it might be somehow amusing to some people, most of whom do not really use C++.

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 stayed away from Stroustrup for a long time, but when I finally cracked the spine and really read it, I was surprised at how rich it was. It's not a dry reference, and it's clearly not terrible. If you're doing C++, you should have Stroustrop.


Practical C++ by Mark A. Terribile is very dense, but clear, and can take you all the way from novice to expert if you can get through it. The copy I have is a decade and a half old, but still relevant for the material it covers, which is substantial. The thing to understand is rarely does the C++ standards committee remove any major feature of C++, they mostly add or enhance, so an old book can still be relevant if it was a well written book, you just might have to look in other sources for other topics.

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.


I came from C to C++ about 5 years ago. I didn't really use any books for the first few months. I have only used http://www.parashift.com/c++-faq-lite/ a lot during this period.

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


Accelerated C++ by Koenig and Moo is a great choice. Stick with it.


If you're on Windows, the MSDN Library DVDs that come with Visual Studio are a great resource. They have accurate and comprehensive documentation on the syntax and standard libraries.

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/


You want the Scott Meyers books, particularly Effective C++ and Effective STL (I don't know if they're still in print, but you want them).

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.


Start by learning C. The best way to learn C is by reading The C Programming Language by Kernighan and Ritchie.

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.


I strongly disagree with this advice. If you want to learn C++, learn C++. Well-written C and well-written C++ look very different, and you want to avoid habits from C carrying over into C++.

That said, the Effective * books are great.


In the beginning, a lot of the foundation of the C++ language was laid by taking things that were design patterns in C and making them language features in C++. While I do not subscribe to the idea that learning one thing somehow ruins you for learning another, it is true that if you start out doing C programming, you'll be doing some extra work that is handled for you in C++ by classes and vtables, and be learning design habits you'd have to drop to effectively use C++ later.


+1 on this. I used to advocate learning C as a precursor to C++, but that changed as soon as I took a C++ course: C and C++ code look completely different.

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.


Raymond Chen has a great quote: "Good advice comes with a rationale so you can tell when it becomes bad advice. If you don't understanding why something should be done, then you've fallen into the trap of cargo cult programming, and you'll keep doing it even when it's no longer necessary or even becomes deleterious." http://blogs.msdn.com/oldnewthing/archive/2009/11/04/9917052...

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.


Here's my rationale: I've worked on projects that were 1 million lines of code and took a minute or longer to link because of the overuse of templates.


This is the typical advice given by C programmers turned to C++.

Illustrating the best reason why you should NOT learn C before C++...


I learned C++ before I learned C. I've been writing C++ for about 12 years now. I was writing production code during Alexandrescu's Modern C++ era.

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.


I would look at Thinking in C++ by Bruce Eckel (http://mindview.net/Books/TICPP/ThinkingInCPP2e.html)

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 like that book too. I am reading it atm. But it might be difficult if you don't have already a programming experience. But for those like me who know C already it is great because it explains all the differences between C and C++ and helps you to fill the gap between both. You can download it for free at the link mentionned above. I find it much more helpfull to learn C++ than Bjarne Stroustrup's book which should be better used as a reference once you know the language.


I'd bet you're maintaining legacy C++ code. If so, while it's good to look at good C++ code (like Boost and the materials you can find on the C++ FAQ) chances are you're going to run into some fairly gnarly code--especially if code has been maintained over several years by several developers. Having maintained C++ legacy code in a commercial app for the last 5 or 6 years--I wish I had some good advice to share. There are a few things:

1.) May sound obvious but good version control is essential. A seemingly innocent change can have nasty side effects. You need to be able to revert to a known to be good state easily.

2.) Watch out for side effects. If something looks odd it may be because there was some very valid reason for the odd construct. Some of the developers working on this commercial app decided to add a copy constructor to a class which never had it before. Ironically, when they added a copy constructor, it trounced all over some bitwise copying code that had been hacked in years before. Hence they had to go back to an older version to straighten things out (see point 1 above).

3.) Add intermediate variables to help yourself understand the code. You'll probably see constructs like this:

func1()->func2()->func3();

This means that func1 returns a pointer which is then used to get func2 which returns a pointer which is then used to invoke func3. This is horrid code but it seems to be a very common antipattern in C++ code (at least in my experience). Adding variables to hold intermediate pointers can help a lot in understanding what the code is doing and in checking to insure that you're testing for bad pointers.

Those are just some thoughts off the top of my head.


I first learned to program using C++ and found this online resource to be extremely helpful:

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.


It's very old and I have no idea how accurate it still is, but I found Inside the C++ Object Model by Stanley Lippman (http://www.amazon.com/Inside-Object-Model-Stanley-Lippman/dp...) to be tremendously useful in the mid-'90s for understanding what was going on under the hood.

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).


Sorry about being a bit tangential. Are you working on the project on your own? If so, then how did you choose C++? To me it almost seems like the wrong answer regardless of what the question was.

What are your prior programming experiences? E.g. if you know Scheme / Common Lisp you'll approach C++ very differently to someone who is coming from a Java/C# background which again is different for a C background.

If you are working with others, then you might want to ask them for their suggestions. And as many have pointed out, it is a rare project that uses all of C++ features, so you'll want to know what the "house style" and conventions are.


I've been working through the Stanford course notes on Programming Abstractions. http://www.stanford.edu/class/cs106b/ Click on the link to the course reader PDF

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.


I love the Meyers books like most everyone below, but I don't think they are a good place to start learning C++. I'd begin with the 4th ed of C++ Primer, which differs from previous editions in that it uses the standard libraries from beginning so you don't spend 400 pages wading through bad code that you would (hopefully) never write in the real world.


<sigh> .. I'd like to say "mu", but here's a bit more. If your project has enough idiosyncrasies to demand C++, then you are best placed to attain guru status in that aspect. So don't listen to gurus and build your own "idioms". The language is bloody flexible for a low level one.


To clarify, I meant "Don't listen to gurus. Build your own idioms instead."


What do you guys think of "Thinking in C++" by Bruce Eckel ?

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


Accelerated C++ was published in 2000 The last C++ standard was in 1998 so it is still relevant to the current standard of the language. The way to learn C++ is to start by treating it like C with a new standard library. Then expand to learn classes and finally templates.


If they treat C++ like C with a new standard library, they are doing it wrong.


The GotW archive is freely available at http://www.gotw.ca/gotw/ and is a good resource for realizing just how much information you need to know to understand a small snippet of C++ code!


Effective C++ from Scott Meyers (and the serie: More effective C++, Effective STL) are the first book that showed me the difference between coding and writing good code in C++. I strongly recommand it.


I'd suggest you to study http://xmlrpc-c.sourceforge.net/ code.


Anything by Scott Meyers. They're really as good as everyone says.


Effective C++ is decent.


You must checkout Cprogramming.com

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




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: