Ask YC: C++
Folks,
I am a Pythonista, and need to learn C++ in a hurry. I have almost negligible familiarity with the language. In a months time I want to be able to hack basic apps in the Symbian C++ environment.
I am looking for suggestions for good books for C, C++, STL and Symbian. Please let me know what you think is the best course of action. Also any advice from your experience is appreciated.
PS: What do you think of C++ as a language?
82 comments
[ 2.9 ms ] story [ 172 ms ] threadObviously, get the SDK, demo apps and start experimenting with it, as you would do with any other technology.
Do you mind if I ask why you need to hack in Symbian C++?
Don't know enough about the Symbian environment yet. Maybe..
It's a bit out of date and it focuses on Nokia's application framework (Series 60). It should be enough to get you writing basic applications though. If you're going to stick with Symbian, don't worry about C or STL. They don't use them.
I assume you're going to be using the more recent Symbian 9. Unfortunately, I don't have any books to recommend for this version. You'll need to rely on the Nokia/Symbian docs for Symbian 9 specific features like Platform Security.
Since you're new to C++, I'd recommend following Symbian's naming conventions religiously. They were very helpful when I was a C++ noob just starting out.
I haven't worked on Symbian in about a year, but if you have any questions, drop me a line (email's in the profile). I'll see what I can do.
as for books, i suggest these two: "the c++ programming language" by stroustrup; and "effective c++" by meyers
It's a great reference but I would never recommend it to someone to learn C++. It's too big with too many boring details that you will probably never run into.
I love to write UNIX tools and network servers in C++. But for projects that don't need the raw speed I simply use Python or Java. You will be 10x more productive in those languages.
One more thing: C++ becomes really nice when you add the right libraries to it. The STL is extremely limited but now with Boost 1.35 things get really interesting.
Check out http://www.boost.org if you are serious about C++.
(Won't help much on Symbian I think, but that platform is terrrrrible anyway.)
I hate C++, although I'm using it right now since python lacks libraries I need (http://www.cgal.org/).
But I hate C++/STL/Boost far less than I hate C++. The STL and Boost make C++ feel almost like statically typed python, (while occasionally driving you mad with pages full of template errors).
An example (g is a graph):
This is almost a direct translation of what I'd write in python (if python had graphs as a data structure), except of course that to_remove is a list of edges.Some people insist on programming C++ like it is c. I.e., they will build an array (hoping it's big enough, sometimes they will even error check if it's not), cast the edges to int's, keep track of how many array members represent edges and how many do not. If you do that, your life will suck.
Except that the C++ version can be highly concurrent and 100 times faster :-)
I'm exaggerating a bit here of course, but in many cases C++ can certainly be a better choice. Even though it is MUCH more verbose.
S.
It's not usually just an inner loop that needs to be carefully optimized, often there various levels of calculation that need to be done.
I'd actually much prefer to use Ocaml for that use case, but libraries made the choice of C++ for me. (C++ is also good to have on the resume.)
That's probably the best introduction book. It's super-long, but after you've worked with C++ for a while you'll understand why. "The C++ Programming Language" has been mentioned here a couple of times, and it's invaluable to have as a reference later in your C++ career, but is almost impenetrable as a book for learning the language.
Accelerated C++ by Andrew Koenig and Barbara E. Moo is a very good book on C++, IMO. It's concise, it doesn't teach you everything but the 80% you will need most of the time and it introduces the STL right from the beginning.
http://www.mindview.net/Books/DownloadSites
1. Languages I chose to learn: BASIC, Assembly Language, C, LISP, Perl, Javascript, Ruby
2. Languages I was forced to learn: C++, Modula-2
3. Languages I have actively avoided: Tcl, Java
if you're in a hurry, maybe you should learn just plain old C, which is a lot simpler, and then sort of quickly rush through classes and other stuff specific to C++.
i'm kind of in the same boat. i'm teaching myself ruby, so i can eventually become an RoR programmer, and join all you hacker news types in the web 2.0 world. before that, i taught myself objective-c, so i could do cocoa programming on the mac. there's some surprising similarities between ruby and obj-c that i wasn't expecting.
When your project grows beyond a certain size, C++ starts to feel like early soviet ballistic rockets: plenty fast, but a nightmare to maintain while on the ground, take forever to prepare to launch and can explode at any moment while in flight.
I used to love it, up until I bought a Pentium-III 800Mz with 512MB of RAM somewhere around 2001.
Stroustrop is surprisingly good as a walkthrough of the language itself.
Modern C++ Design by Alexander Alexendrescu is the best advanced book.
Accelerated C++ by Andrew Koenig and Barbara E. Moo
Second:Effective C++ by Scott Meyers
Reference:The C++ Programming Language Bjarne Stroupstrup
If you want some Guru level references I can list a couple more advanced books if your interested...imho, the fundamental problem with the language is the principal of maximum-surprise. what you don't know can really hurt you...
There are so many crooks and nannies, pitfalls and gotchas in the language that most people either give up, or they take the time to learn to do things the "right" way. I fall into the latter group.
However, I absolutely despise the C/C++ compile/link model. And I hate STL errors, or any sort of error that arise from the incorrect use of templates. And header files need to die.
I learnt most of the C++ I know from tutorials on the Web.
Start by following along with some basic C++ tutorials. Once you're comfy enough, start implementing your own small applications. (Write a program to accept a sentence from the user and print it out. Then write a function that takes two strings and returns true if the two strings are anagrams. Keep thinking up small apps.)
It is my opinion that you must avoid learning STL and Boost if you want to be productive within a month. Both libraries have enough quirks that it takes a significant amount of time and experience to use them correctly. For example, you don't need the std::vector or std::list containers. Simply allocate a sufficiently large array to hold your items, then allocate a larger array when the first one fills up. A std::map container (a dictionary) is also not needed if you're tracking a small number of items. Simply loop through all items until you find the one you're looking for.
Basically, start actually writing code as quickly as possible. If you feel like you're burning too much time trying to understand one tutorial, move on to another one. But make sure at the end of each day that you can look back and say, "I wrote a lot of apps today and I feel like I learned a lot."
Most importantly, don't be afraid to throw your old code away once you have a better understanding of how best to solve the problem. Implementing components as quickly as possible is the key to productivity. Rewriting your old code is the key to not making a mess.
Contact me at palish@gmail.com if you have any questions along the way. I'd be happy to help. I'm a self-taught graphics programmer, so I can relate to how scary C++ can seem at first. Try to implement each application in the simplest possible way.
If you're used to python, you probably have a very list- and dict-centric method of programming, and you are probably not very familiar with explicit memory management. vector and map are pretty simple and correspond closely to the python list and dict classes.
In fact, I would recommend that new c++ programmers used to scripting languages avoid using "new" entirely. With vectors and maps this shouldn't be too hard.
1) It is important to write STL code in the correct style. STL containers should be typedef'd before they are used and an iterator shouldn't be used directly to access an item (otherwise debugging becomes more difficult and your code becomes harder to read). For example,
... rather than ... 2) STL frequently allocates memory. Those allocations are also hidden from you, so it is easy to misunderstand the true cost of frequently using STL containers. Even a simple operation like acquiring an iterator can cause an allocation.I work at a game company. In their game's code base, the pervasiveness of STL has been attributed to millions of micro-allocations every frame of their game. (A micro-allocation is an allocation of under 128 bytes.) The result is hopelessly fragmented memory, which means that:
- A relatively small 10MB allocation can cause a crash even when there is clearly more than 10MB free memory.
- A lot of code runs slowly because almost none of the code can take advantage of the CPU cache.
3) Using STL can add code complexity and make your code harder to read. Which of these is easier for a newcomer to understand?
... or ... The second example isn't intuitively easy to write unless you're already familiar with std::map.Check out my Radix Sort example. I could have used a couple std::vectors, but the result is equivalent and simple: http://dl.getdropbox.com/u/315/programming/exaples/radix_sor...
4) It takes a lot of time to learn every facet of the C++ language. And the more you learn, the more other people can't read what you write because of your advanced knowledge. (Try understanding boost/bind.hpp.)
5) Most importantly, most design problems are architectural and not structural. As long as your code works and is reasonably clean and well-commented, it is good and safe code. It is more important to master a subset of C++ than to have a working knowledge of the entire language.
Unless you're counting stack too. I could see STL implementations combined with a compiler poor at inlining resulting in a lot of extra call depth.
Edit: Also, if the original poster is mostly using C++ due to the platform (I don't know what Symbian supports) it's unlikely he has the same sort of performance requirements you do. Most applications don't need to worry about 128-byte allocations.
A big culprit is our pervasive use of std::string, but every other container also contributes.
On point 1, I see nothing wrong with this:
Use typedefs for more complex templates. My rule of thumb: if it's faster to read and understand the template than to find the typedef, don't use a typedef.As for the allocations (point 2), not usually a big deal outside of games. The added safety is worth the performance hit.
Not only that, but using Boost results in non-portable code. Boost could be the reason that your game cannot be ported to the PS3 or to the XBox 360 platforms. (Both STL and Boost can also consume a lot of precious memory on those platforms.)
Also, there is still a huge market outside of games where it isn't necessarily a good idea to use STL and Boost. Embedded systems, flight simulators, so on. How do you know that STL and Boost compile to equivalent code when your compiler isn't GCC or Visual Studio?
So Boost limits your options and it is debatable whether its productivity return is greater than its cost. In that light, why is it a good idea to train yourself to depend on it?
If you take a job at a company where Boost is not an option, you will:
- be forced to not use any code in your personal library that references Boost.
- be forced to expand all of the BOOST_FOREACH() statements into for( std::list< Puppy >::iterator ... ). (Also, you left off the std:: on "std::list". I'd like to mention that "using namespace std" is a bad idea.) Because of that, typedef'ing each STL container before using it is a good idea. As for finding the definition of the typedef, the definition should almost always be within the same class that uses it. If you install Visual Assist you can use the "Go To Definition" feature (Alt-G) to warp directly to the typedef's definition.
If you're forced to use C++, I assert that you can be more productive, portable, efficient, and reliable by avoiding Boost and most of STL.
Further, I'm mystified why you said learning the STL is premature optimization, and then further advocated premature optimization regarding memory allocation. I don't see how learning the STL is a premature optimization. As for your performance problem, STL containers can take a custom allocator as a template parameter.
Getting all of the details of the STL right is tricky and takes time, but using the simplest features is still the fastest way to write good C++ code. Since he already knows Python, it's mostly a matter of mapping the concepts from one language to another.
I can't stress this enough. If you find yourself thinking, "Hmmmm, I need a list of these," use std::list. If you find yourself thinking "Hmmm, I need a structure that maps these values to those values," use std::map.
When learning a new language, I think it's best to start using that language's idioms right away. C++ is no exception.
It may take a little bit longer to learn how to use the STL container classes, but the time is well-spent, and you can't make a legitimate claim of "knowing" C++ until you're comfortable with them. They're part of the language!
Bjarne Stroustrup wrote a good paper on learning C++ as its own language. I highly recommend it:
http://www.research.att.com/~bs/new_learning.pdf
The advice was based on being a professional C++ programmer for the last 3 years and a C++ tinkerer for 5 years before that. I thought there was some merit to it. If it was really that horrible, I apologize.
The reason that your advice was so bad, was that you were encouraging someone to lunge headlong into the worst parts of C++ programming, while simultaneously warning them off of the best parts of the language. I've been a C++ programmer since the mid-90s. I learned the language before the STL (or the 1998 standard), and I know from hard experience that C++ with STL is a very different (and far more productive) tool than C++ without STL. In other words, I learned it the way that you suggested, and I know from experience that's the wrong way to do it.
(Note: I have edited the original comment to be slightly less extreme.)
sigh. Yes, you do need std::vector and std::list. Those are the very first two data structures you should learn. If you're using int[] instead of std::vector<int>, there'd better be a good reason. Similarly if you're using char * instead of std::string. Learn to use iterators, and learn to use <algorithm>. Don't be afraid of streams, either. I think doing it any other way is just wasting time and making it harder to actually become proficient in C++, rather than just using the C++ compiler to give you C with a tiny bit of syntactic sugar.
IMHO, it's much better to learn the ins and outs of STL as you use it, not by putting off using it until you master it all (what kind of logic is that, anyway?). I.e., it's way better to start off using a std::vector exactly as you would an array and learn it as you go than to put off using std::vector entirely until you understand the default allocator and operator overloading.
My point was, kashif wanted to be productive in C++ within a month. It is not reasonable to expect him to become familiar with all of the STL and Boost quirks within a month. He has a better chance of accomplishing something by using C++ as C plus constructors than by using C++ as a high-level language. The latter requires expertise and a large time investment.
In my example, the only difference is that numbers is initialized with a () instead of [].
As for the call to memset(), looking at the documentation for API to see that you empty the vector with
is not getting "burned by quirks". That's how you go about becoming productive in C++, which is what he wants. Also, getting burned by memset()-ing an object is not a quirk of the STL.In general, what I'm not arguing is that he should use the entire STL right away. Of course you'll get burned by doing stupid stuff that you'll later realize is stupid. What you're arguing is to avoid the STL alltogether, and instead write C in a file with ".cpp" at the end, which is equally bad (because it's not productive C++).
The way to go is to put into practice the bits and pieces of the STL that you can right away. std::vector and std::list are the simplest containers, the fastest to learn, and the most commonly used, so he should start there. Once he discovers iterators, allocators, and <algorithm> (oh my!), he will wake up one day and realize that he now understands a large chunk of the expressiveness of C++.
If learning C++ is the goal (and he stated it so), then he should use C++, which is how he will get the "sufficient knowledge" you seem to see as a roadblock.
And by the way...it's long since past time that we stopped calling it the STL. It's been a standard for plenty long enough that we should all be calling it the standard library.
I'd like to ask, are you understanding my point? An amount of open-mindedness is required. Common wisdom has been proven incorrect time and time again throughout history, and the common wisdom of C++ that "you need to use STL containers and Boost to be productive" is incorrect.
Pierre can illustrate some of the issues more succinctly than I: http://72.14.205.104/search?q=cache:UV4RcASt8mMJ:www.coderco...
'Alex named his containers, iterators, and algorithm library “the STL”. Usually, that’s considered an acronym for “Standard Template Library”. However, the library existed —with that name—long before it was any kind of standard and most parts of the standard library rely on templates. Wits have suggested “STepanov and Lee” as an alternative explanation, but let’s give Alex the final word: “ ‘STL’ stands for ‘STL’ ”. As in many other cases, an acronym has taken on a life of its own.'
http://www.research.att.com/~bs/hopl-almost-final.pdf
You can't memcopy directly into the address of an object...
This isn't STL specific... you need to learn this if you plan on using C++ period.
For STL, I recommend Josuttis's "The C++ Standard Library". It's a STL reference book, very complete and easy to browse. There are also brief examples on own to use the classes and templates. http://www.josuttis.com/libbook/
Or just give yourself challenges. Rewrite some non-trivial code you did in Python to use C++, for example, and ask experienced C++ people to comment.
Also, as others have said, use Boost and STL if you value your sanity.
In practical terms, I'd rather use C+Python or C+Ruby than C++. I template in a high-level language and move the stuff in tight loops or otherwise performance-critical sections into C.
Personally, I think C++ is a great language. Many people don't think as highly as I do of it, instead preferring some of the more dynamic typing languages, but you have a lot of power at your disposal once you manage to wrap your head around it.
I got started with C++ because I come from a financial background, and most financial apps in the real world are written using C++.
Why do you have to learn the language within a month?
Here is what I recommend.(order by preference)
1. http://homepage.mac.com/s_lott/books/python.html 2. http://www.diveintopython.org/
I'm a big fan of Dive Into Python too, but I'd recommend that for developing good python techniques, rather than getting quickly up to speed.
By doing that, I absorbed some of the important languages concepts and capabilities. I find that I learn best by example; show me what a correct solution looks like, and I'll figure out why it's correct, and hopefully generalize that to the whole language.
Once I started doing some Python programming, I jumped to mostly using the online library and language documentation.
Disclaimer: I still haven't used Python extensively, but I feel comfortable when I use it.
Oh, and a Safari account will go a long way to help you quickly find relevant GOOD material (not just script-kiddie posts).
Although, it depends on what you mean by "Hack basic apps", doesn't it?
If you're working on existing apps then you'll need to know the same subset of the language that the original programmers knew. If you're going to write apps from scratch you might do very well by starting only with the Symbian programmers documentation, if it's good. Beyond that, just learn C and use C++ as a "Better C".
If you can avoid using classes and templates you can start quicker.