views:

3384

answers:

21

While reading a long series of really, really interesting threads, I've come to a realization: I don't think I really know C++. I know C, I know classes, I know inheritance, I know templates (& the STL) and I know exceptions. Not C++. To clarify, I've been writing "C++" for more than 5 years now. I know C, and I know that C and C++ share a common subset.

What I've begun to realize, though, is that more times than not, I wind up treating C++ something vaguely like "C with classes," although I do practice RAII. I've never used Boost, and have only read up on TR1 and C++0x - I haven't used any of these features in practice. I don't use namespaces.

I see a list of #defines, and I think - "Gracious, that's horrible! Very un-C++-like," only to go and mindlessly write class wrappers for the sake of it, and I wind up with large numbers (maybe a few per class) of static methods, and for some reason, that just doesn't seem right lately.

The professional in me yells "just get the job done," the academic yells "you should write proper C++ when writing C++" and I feel like the point of balance is somewhere in between. I'd like to note that I don't want to program "pure" C++ just for the sake of it.

I know several languages. I have a good feel for what "Pythonic" is. I know what clean and clear PHP is. Good C code I can read and write better than English. The issue is that I learned C by example, and picked up C++ as a "series of modifications" to C. And a lot of my early C++ work was creating class wrappers for C libraries. I feel like my own personal C-heavy background while learning C++ has sort of... clouded my acceptance of C++ in it's own right, as it's own language.

Do the weathered C++ lags here have any advice for me? Good examples of clean, sharp C++ to learn from? What habits of C does my inner-C++ really need to break from? My goal here is not to go forth and trumpet "good" C++ paradigm from rooftops for the sake of it. C and C++ are two different languages, and I want to start treating them that way. How? Where to start?


Update:

Based on the responses thus far, it seems that a few readings were commonly recommended:

The three Scott Meyers books seem popular:

A book (C++ Coding Standards) by Herb Sutter also comes recommended with a reasonable justification.

Along with Beyond the C++ Standard Library: An Introduction to Boost by Björn Karlsson, there were many references directly to the Boost and STL documentation respectively.

A few folks mentioned taking background information right from the horses mouth. The C++ FAQ Lite was brought up - and seems to be a great resource to either read as a learning tool, and as a quick reference guide. Another great suggestion was to follow by the example of our resident SO pundits by perusing the C++ Leaderboard.

Based on votes (there were many great answers) I'm going to accept the answer of Brian R. Bondy.

+35  A: 

Great question, there is a big difference between the C language and the C++ language. Each has its own specification and own benefits and differences. And you are right that it's common for people to write C/C++ code. It has also been my goal for the past few years to write less C/C++ code and more C++ code. There's no overnight fix, just decades of experience that will get us there.

By heavily learning and using STL and boost you will dramatically increase the quality of your code, and it will help you get away from C like code.

I would suggest getting a book on each of those topics if you want to increase the quality of your C++ programs. Something like Effective STL and Beyond the C++ Standard Library: An Introduction to Boost.

Little things can help you get away from C like code in the short term though. For example using smart pointers instead of raw pointers, using vectors instead of dynamically sized arrays. Using STL algorithms and iterators. Using RAII instead of managing resources directly. What you'll start to find is what used to take you 10 lines of code now takes you 1.

Also answering questions on stackoverflow really helps as well. You will get corrected by others, and see alternate answers for questions that are more C++ than your C-ish answer.

Lastly there are a lot of great "real C++" developers on stackoverflow. Consider reviewing their profile answers and learning a little from their answers every day. I don't want to name anyone in fear of leaving someone out, but check out the leaderboard for the stackoverflow C++ tag. The top users really do offer a lot of insight to learn from in their answers.

Brian R. Bondy
Oh! I didn't know about the leaderboard. Neil's frightening.
Matthieu M.
fantastic answer Brian. I really do believe that anyone benefits from the great community on Stackoverflow. Learning from one person with years of experience is great, learning from a community with hundreds of years experience combined is even better!
PieterG
A: 

Read or participate of proper source code of project in C and C++ and Learn from their difference.

Phong
+10  A: 

Go to the language's designer, Bjarne Stroustrup's home page and learn what he has to say about the topic: C++

Khorkrak
+18  A: 

I recommend everyone read Scott Meyer's great 3 books on C++ programming (Effective C++, More Effective C++ and Effective STL), at least as a start. Between those and becoming familiar with the C++ Faq Lite you should start to get a good idea of what constitutes proper C++ without getting bogged down in too much cruft.

brandonC
+1 for C++ FAQ Lite.
Michael Aaron Safyan
@MAS not to be confused with steaming pile which is FQA
aaa
+1  A: 

Using exceptions, PIMPL approach and understanding C++ Exception safety guarantee will undoubtedly make youe C++ coding shift gear.

Igor Zevaka
+6  A: 

C++ is a complicated language. B. Stroustrup said "Yes" to many features. (And therefore the language was quite successful.) As a result, though, there are many ways to solve problems in C++.

Three programmers working on a team can use completely different subsets of the language, and their code may not even be compatible. One of the first activities of starting a project is figuring out what subset of C++ you will use. Any project needs a project style guide. I suspect there is no definitive style, like there are in other langauages. Therefore I see why you don't feel like you know all the aspects of it.

Contrast this to Java-- that was very much a response to C++. It's much smaller and completely understandable-- you really can use all of Java's features on a project, AND expect all programmers to be able to read your code. I haven't worked in C++ for years (although I was an expert at one time), but I found that expecting developers to have a strong grasp of the language wasn't realistic-- it was just too complicated and had/has too many "gotchas".

Anyway, back to your question. If you really want to learn a language completely-- be it C++, Java, CSS, Javascript, or whatever-- you need to read through the thick reference books, slowly. I remember being fascinated through Stroustrup Annotated C++ Reference. There's probably a much more current book, but after getting through a book like that, you will at least know you have explored all the rooms in the house.

Another good tactic is to find code to read. This used to be much harder than it is today, with all the open source projects out there. Some of it may not be that gratifying, but look around. It's a great way to improve your knowledge of the language. I've been meaning to dig into Chrome and Firefox source...

ndp
+1  A: 

A really good resource that hasn't been mentioned: C++ Templates by Vandevoorde and Josuttis.

Also, Scott Meyers gave a talk called "False Friends" where he talked about ways in which what you know about C will confuse you in C++. I can't find a copy online, unfortunately, but I bet it's out there somewhere. And I'll second the recommendation of his 3 "Effective..." books.

I found Generic Programming and the STL by Austern to be really useful in understanding not only the STL, but the idea of "concepts" (in the generic programming sense). The STL and generic programming are pretty central to modern C++ design, but are pretty alien when coming from C.

jwismar
+2  A: 

Get a copy of the C++ standard (or maybe one of the drafts).

Read it, learn it, memorize it, sleep with it. Only then will you become one with C++.
...that and there will be a 500 question quiz tomorrow. Read fast because there are 776 pages.

Oh and, please keep it in PDF format, I kill enough trees daily :).

But in all seriousness, reading the C++ standard will let you glen deeper into the language than any tutorials.

Nathan Adams
-1 I don't think reading a language standard makes you a better programmer. It's useful for clearing up language constructs that you don't understand, but not make you a better coder.
Igor Zevaka
@Igor - It will, because then you will know all the features of the language and be able to find more information on a specific feature rather than reading some 500 page book that contains most of the information but I am sure leaves some stuff out. Also a "learn C++ in 24 hours book" will likely ALOT of stuff you already know, the C++ standards will probably contain stuff that you didn't even know where available in the language.
Nathan Adams
I respectfully disagree. The standard is something that you look into as a professional developer when you find a quirky feature. It could also be a useful companion when you finally get a hairy header file to compile to help you understand why it wouldn't compile before. It's not a place to start, but a place to finish. Also, ability to design your program properly (short functions, classes, SRP, encapsulation etc) will always trump the technical knowledge of the language.
Igor Zevaka
@Igor I agree that is isn't a place to start, however, in the OP post he says "I've been writing "C++" for more than 5 years now." He isn't "starting" to program C++, he is already knee deep in it. Would you not agree?
Nathan Adams
[Studying language standards] cannot make anybody an expert programmer any more than studying brushes and pigment can make somebody an expert painter. – Eric Raymond (with apology for changing "Computer science education")
Roger Pate
@Roger that is a fallacious argument - if a painter is not familiar with brushes or pigment, then how could they ever be a professional painter? Your same argument would be "Why should a C++ developer learn the parameters to the complier/linker?" Also I think you all missed the part where he says he has used C++ for FIVE years already. No tutorial will cover every feature of the language. In fact, how do you know that the tutorials you are reading are actually standards complaint if you don't know what the standard is?
Nathan Adams
@Nathan: You misinterpret: the quote is not saying you can be ignorant of brushes or pigment and still be an expert painter. Perhaps mangling another quote will help (apologies to Edsger Dijkstra): Programming is no more about language standards than astronomy is about telescopes.
Roger Pate
@Roger But how can someone call themselves an expert in a language if they don't know how to code per the standard? I think the reason why we have such a variety of C++ styles and crossplatform/non-crossplatform is that there isn't enough stress on the standard itself.
Nathan Adams
+3  A: 

Dude, that's deep existential question you're asking here. We're all on the same path with you... (C++ is a lifestyle)

deian
I think you should lay off the magic dragon.
Nathan Adams
+1  A: 

I suggest that you learn from the following books in order:

  1. The C++ Programming Language
  2. Effective C++, Effective STL and More Effective C++

Get familiar with the Boost C++ libraries and use them in your projects.

Vijay Mathew
+3  A: 

I think the answer is as usual when you're trying to learn something - read more C++ books. In that list you want to read Intermediate and Above Intermediate sections. Lots of good programmers stops at the Beginner section and they still use some sort of C-with-classes-and-STL language. Effective C++ is a really good book but that is not enough.

As for Boost... Using Boost is not necessary a sign of a good C++ programmer. Some companies restrict using of Boost but there are still good C++ programmers working there. If Boost is allowed in your company it helps to write less code, but this code could be less clear for your co-workers. But sometimes Boost is a definite choice. In that case you could feel it while looking at list of Boost libraries. The other way do not use Boost only for using Boost, or because you're trying to be C++ programmer.

Kirill V. Lyadvinsky
especially "C++ template metaprogramming: concepts, tools, and techniques from boost and beyond ". some of the stuff in book is borderline magic
aaa
And your head likely to explode, that's certainly not bedtime reading material!
Matthieu M.
Most of good C++ books is not a slick fiction.
Kirill V. Lyadvinsky
A: 

As I am doing the same. Read any good C++ book and chaperwise try some demo programs by self. This will definately help you. I tried demo codes for inheritance, virtual functions & pure virtual functions, function overloading, ctor overloading, copy ctor, uninitialized object (with overloaded ctor), operator overloading, templates with functions, templates with classes.

Shrikant
A: 

To really learn properly, you need to start building a small application which will surely improve your ability to use all the features of the language. And please look for some sample applications beside reading.

http://www.cplusplus.com/src/

hope this link will help you

sdr
+10  A: 

Firstly, you say:

The professional in me yells "just get the job done," the academic yells "you should write proper C++ when writing C++" ...

You could of course substitute any language for C++ here. The fact is that doing the job properly will always, even in the short term, be quicker than "just getting it done". This has been proved time and time again - "code & fix" programming is a project killer.

To turn to the things that you say you do/don't use:

  • RAII: Use of this is the absolute key to being a successful C++ programmer. Although you say you do use it, do you use it all the time? In other words, are all your classes self-managing in the face of exceptions? If not, a good start would be to ensure that they are.

  • TR1: There is nothing in TR1 that you absolutely have to use, and I don't use anything from it myself, for portability reasons. Not dong so does not make you a bad C++ programmer.

  • Boost: For a long time I resisted boost, once again for portability reasons. However, it does have some seductive features such as its excellent random number library and smart pointers, and I will certainly use bits of it on future projects. However, you don't have to embrace the whole thing or become an expert on it.

  • C++0x: Once again, no need to know anything about this yet to be a good C++ programmer. This Standard has still not been accepted, and it's unlikely that your compiler supports it fully. As with any new thing, I prefer to let others do the experiments in their own code, rather than me doing it in mine.

Two things you don't really make clear in your question:

  • How well you know template programming? You really need a good grasp of this in order to be an effective C++ programmer. I'd recommend reading C++ Templates: The complete Guide to get this grasp.

  • How well do you know the current Standard Library? Absolutely essential to know what is available and how to use it - you must (IMHO) have a copy of Josuttis' book.

Anyway, don't get disheartened - I probably know less about C++ than I did 15 years ago (when I had the job title C++ Guru - something I cringe about now) due to the way the language has grown and ideas about using it evolve. But I still love it, and think it the best general purpose/systems programming language around.

anon
This contains a real truth: doing the job properly is *quicker* than the alternatives. +1 from me.
Francesco
The professional in *me* yells get the job done *right*. ;)
Jake Petroules
+2  A: 

Shift from the data manages itself idiom to a who should I tell to do this? idiom.

As an example, of data that manages itself if you had a FILE* in C - in C++ you'd have a class file for it. It's not bad, but it's C with classes.

If you ask instead who should I tell to do this? your answer may not be "a File". It may be "a stream" (implies a different public interface), "a logger" (another interface), or "some transactional storage" (yet another public inteface). Basically it shifts your design from data-centered to semantics-centered.

In the same direction, design your interfaces before deciding your implementations. This should take you even further from "wrappers around data".

Other things:

  • Use boost. It was designed to create production-ready stable code and promote best practices. It not only provides you with ready-to-use bits but it changes the way you look at some things. For example locking a boost::mutex with a mutex::scoped_lock imposes usage of RAII, unless you make real efforts to break the design (not recommended).

  • Use C++-specific optimizations and patterns (use RAII for example). Familiarize yourself with all of C++. That improves your understanding, gives you more options and makes you a better programmer.

  • Make exercises for specific C++ constructs (outside your production code) and look for places where those constructs would prove an advantage (write a few functors and some code using lambdas, some smart pointer class and so on but if they are available in STL use those in production code).

  • Group your application domain into functional areas/different domains and separate the areas as namespaces (diagnostics, io/serialization, xml, etc.)

  • Write generic code. If you can write your sequence-processing code to receive a pair of template iterators, that's much better than receiving a std::vector<?>. It also makes sense to write templated versions of your operator << that apply for char and wchar_t than having the same function written twice.

  • split common identifier names into namespaces. That is, if you have xmlnode, xmliterator, xmldocument and so on, you're better of changing that to namespace xml and xml::node, xml::iterator, xml::document and so on).

utnapistim
+2  A: 

The best way to learn C++, is to use it. Don't get me wrong - there are LOTS of EXCELLENT books and other resources available - but the hardest, but best, way is to fire up your IDE, write some C++ code, and if it does not work, debug it, ask specific questions relating to specific error messages you get, and learn by doing.

Marius Myburg
A: 

Your problem is not C++. It is about "Object Oriented" programming as opposed to "Procedural" programming. How can I take a problem and design an object oriented solution to it - thats your issue.

The best way to learn a technology is to read good codes written by others. So heres what I would suggest:

Download Qt (a cross platform gui development toolkit) and create some guis of your own. It is free as long as you do not use it for commercial purpose. It is good C++. They have tons of tutorials/demos in there. Good thing is - you can see the objects on the screen & touch & feel them (derivation, virtual, containment, etc.). You can download their source code too - a good reading.

And here are three imp sentences that you need to know in OO coding (Dont know why it is not mentioned explicitly by the gurus anywhere):

  1. isA: If X isA Y, you can derive Y from X (eg. Cat isA Animal, Circle isA Shape, Engine isA Part)
  2. hasA: If X hasA Y, X contains Y or Ys (eg. Car hasA engine, Car has Parts)
  3. base* = derived*

And then comes Templates, STL, MVC, ...

Good luck.

sambha
No, OOP has little to do with good idiomatic C++. OOP is where you end up if you go the route the OP has already gone: Start with C, learn that C++ has classes and inheritance. He's there already. And that's not C++, it's C with Classes.Modern C++ is something almost entirely different, and preaching OOP as some kind of universal truth isn't going to get him there.
jalf
Hmmm. Should read these more carefully.
sambha
Aside from what jalf said, QT is not a particularly good example of well-written C++ code. Just consider its memory management, for instance: it's g-awful. Regardless, I still use it for its cross-platform capabilities, but I don't think TrollTech would have implemented their library this way if QT wasn't initially created in 1991, 7 years before C++ was even standardized and long before effective use of C++ was well-understood.
Got it guys. Stop -ve ing
sambha
A: 

You say "What "Pythonic" is" meaning about its style. For a 15 minute review about C style, check :

About C++ Style

  • C++ Coding Standards: 101 Rules, Guidelines, and Best Practices

Some C++ idioms: - More Idioms

For a deeper knowledge about differences, first know about C taking a look at "C Programming Language (2nd Edition)".

Then, having some knowledge about C++, I recommend reading Effective C++, More Effective C++ and Effective STL by Scott Meyer for efficiency, and Bjarne Stroustrup's book for a more academic approach.

Later, read Modern Design C++: Generic programming and design patterns applied. It tries to present C++ as a newly discovered language for software architects. Seriously, at least take a look at the sample chapter.

+2  A: 

Reading "Thinking in C++" by Bruce Eckel from cover to cover and do all the exercises in the book.

Paul Reiners
A: 

Reverse Engineering 101 -->it can create miracles, you may find yourself debugging someone else's C++ code, but actualy frankly this may not be a satisfactory answer to your question because as the name implies reverse engineering is not a proper way of learning:(

Başak Bilgi
+3  A: 

I'd like to add a bit to the discussion even though you've already chosen your answer.

Meyers books are very in-depth and not a light read. If you want an introductory overview to get you to step back and start thinking in the right direction, I recommend Sutter books, particularly C++ Coding Standards. The title turns people off, but the book does not preach style: it talks about why C++ developers do things a certain way. It's a small book and a very light read yet it's a book you can come back to again and again. When you have read that, it will become a lot easier to understand Meyers at a very practical level.

As for understanding boost, I don't recommend that you try to understand how boost is implemented so much as how to use it unless you want to be a boost contributor. The reason boost code looks so obfuscated is because it has to support a very wide range of compilers including some really awful ones that are not very standard-compliant at all. Without those, you would not see code littered with #ifdefs, sub-wrappers, and so on. If you're tracing code with a debugger and you end up in boost territory, I recommend you step out fast: focus on the client code using boost.

Anyway, I seriously recommend you check out the book. It should answer all of your questions concisely and really give you an understanding of why people do things a certain way.