tags:

views:

380

answers:

8
+4  Q: 

Java to c++ guides

Are there any good guides online to prime an advanced Java user for advanced C++ in a short period of time?

+4  A: 

Its not specific to Java programmers, but I find this SO thread very helpful.

Adeel Ansari
It's good, but in the short term those books might be overkill. I'll keep it for later reference, thanks.
piggles
Yeah, sure. The thread including folk's comment will help you decide on a single appropriate resource for yourself.
Adeel Ansari
There are indeed many books listed in that thread. However, /Accelerated C++/ may be what you need (as well as many people with years of C++ behind them) as it puts an emphasis on the C++ standard library from the start, as the value vs entity dichotomy is present in the way the chapters are organized, etc.
Luc Hermitte
There's nothing "overkill" about learning the language properly. It's a complex language to learn, and it's easy to introduce *a lot* of subtle bugs if you don't know what you're doing. "In the short term", all you'll be doing is wrecking your own code.
jalf
+2  A: 

This might be useful:

C++ Reference guide

Andy
Let me just say that the author of this series is not well-respected among most of the C++ experts.
sellibitze
+7  A: 

Apart from some minor syntax, the two languages are completely different, so you will have to read at least one book to get up to speed - online "resources" simply will not cut it. For an experienced programmer, the obvious choice is Stroustrup's The C++ Programming Language. I would back this up with Josuttis's The C++ Standard Library.

anon
When you say completely different, does that mean the structure of the language is different, or the basic API's are different? An API is easy to learn. What I'm worried about is things that don't behave the way you'd expect them to. (And I can't enumerate, because then they wouldn't be unexpected in the first place)
piggles
The programming model is completely different. This includes stuff like how memory is managed, how object lifetimes work, how function calls are resolved etc. etc.
anon
Many things don't behave the way you'd expect them to when coming from Java. In Java, everything you do is nailed down and well-defined. Your code *always* behaves according to sepc. In C++, unless you're *extremely* careful, you'll run into Undefined Behavior which means *no* rules apply. Even code as simple as `a[++i] = i` is undefined. It won't give you an error, it'll just yield an unpredictable result. Or `foo(++x, ++x)`. In Java, if you violate the language rules, you get an error. In C++, it'll typically seem to work, and it's up to you to *know* that you just violated one of the rules
jalf
What do you mean it's undefined? and why does this make the process significantly difficult? I'll get back to you in a week or so. I think I'll take the encouragement of others over you're rainclouds... Especially since people who I taught java last year are now programming for big companies in C++.
piggles
What "encouragement of others"? Everyone here seems to be saying "no way, without reading a book."
anon
@Mechko: By "undefined" I mean exactly what a dictionary would say: "Not defined". The C++ language specification does not say what should happen. It could work as you expect, it could do something you don't expect. The compiler could generate a warning or an error, or it could be silent and just accept the code. It could format your harddrive or make demons fly out your nose. Or it could overwrite a few bytes in memory that won't cause any problems until two hours later in a completely different part of the program. And there'll be no way to trace the problem back to the source.
jalf
@Mechko: What you need to know is how to recognize and avoid undefined behavior, which takes some experience. One issue is that undefined behavior won't always bite you, but I wouldn't consider somebody advanced in C++ if they wrote something like `a[i++] = i;`, even if it had always worked exactly as they expected.
David Thornley
I have to say that I think UB is a bit of a red herring in this context - if C++ didn't have UB it would STILL take a lot more then glancing at a website to transition from Java to C++.
anon
http://stackoverflow.com/questions/2028464/logic-differences-in-c-and-java is a great example of why UB is *part* of the reason. In java, you can just write the code, see how it is evaluated, and trust that this is How It Works. The C++ version requires you, the programmer, to know that what you're doing is not well-defined, and that you're getting what's basically arbitrary garbage out. The compiler won't tell you that. No runtime checks will either. You just have some puzzling inconsistent behavior and if you try to build an understanding of the language based on that, you're screwed.
jalf
But yeah, you're right, UB certainly isn't the *only* reason why transitioning to C++ takes more effort than just reading a few online tutorials. But it's part of it.
jalf
+15  A: 

No.

There isn't.

There is one very important difference between the two languages. Java is well-defined and nailed down. If you do something wrong, the language spec defines what should happen: Either the code should behave like this (which may not be what you expect, but is at least deterministic and verifiable, so you can find out that you were wrong), or the compiler should generate an error.

In C++, there's no such luck. The language spec only defines what a program should behave like if you write it correctly. Of course it also defines some errors that must be caught by the compiler, but in most cases, if you do something wrong, you have a program that compiles, but whose behavior is not defined by the C++ specification. It exhibits Undefined Behavior.

And you have no way of knowing this. There are no warning lights. No compiler errors. No crashes before everything go seriously wrong. It probably won't even be consistent or repeatable. One day, the program will run fine, the next it'll crash. It'll run on my system, but crash on yours. And it might not crash when you make the error. It might corrupt some rarely-used bit of memory, so that two hours later, the application will crash.

In Java, "learning by doing" works pretty well. You just have to learn the basics of the language, and the rest can be figured out by listening to compiler errors and by looking at your code in the debugger.

In C++, you'll crash straight into undefined-behavior land, and your code will seem to work fine in the debugger. And then it'll crash 20 minutes later in a completely unrelated piece of code. Because you did something wrong earlier on, in the bit of code that you actually checked in the debugger.

Many simple constructs are undefined in C++:

int a[10];
a[i] = i++; // will the old or new value of i be used to index the array? Undefined
int* p = a+11; // undefined. Pointers pointing out of bounds aren't just "not allowed". They yield undefined behavior. Simply creating the pointer may or may not crash your program, or corrupt the process memory, or anything else you can think of.
f(foo(x), bar(x)); // will foo or bar be called first? Unspecified.

These are just a few examples of very simple operations that seem to work, but which can and will blow up in your face. (The last one is a bit safer, because it's not undefined, it doesn't throw away all guarantees about your program. You simply don't know which parameter is evaluated first.)

Are there any good guides online to prime an advanced java user for advanced C++ in a short period of time?

So no.

  • There are no good guides online to C++.
  • There is no way to become an advanced C++ programmer in a short period of time.

You'll have to take the long route. Learn the language first. Take the time you need for that. Of course this doesn't mean that it is impossible to learn C++. Just that it is much more complex than learning Java or Python. Partly because the language is just much more complicated, but also because you have no way of knowing whether your program actually stays within the boundaries defined by the language -- it might rely on something that's not specified in the C++ standard, and then all bets are off.

jalf
That seems a little harsh. Simply because it's harder doesn't make it impossible. I taught myself enough python to write client-side applications for my java server in about a week. C++ can't be that significantly more difficult, can it?
piggles
Unfortunately C++ is very considerably more difficult than Python. In fact I'd put them at completely opposite ends of the "ease of learning" spectrum
Don
Compared to python, the learning curve of C++ resembles something, that could be described as a "mountain, followed by a wall".
shylent
Heh, it took me about 3 days to learn python. I'm still learning C++ after about 10 years of using it off and on.
Chinmay Kanchi
@Mechko: I never said it was impossible. I said it is in a completely different league, difficulty-wise, than either Java or Python. And I tried to explain *why*. Both Java and Python guarantee sane behavior if you screw up. C++ doesn't. Both Java and Python can be used without understanding the language. In C++, that's just a recipe for subtle unreproducible and hard-to-track bugs
jalf
+1. It does sound a little harsh but that is actually exactly what the OP needs to hear as he's obviously underestimating the "issue"
sellibitze
+9  A: 

Are there any good guides online to prime an advanced java user for advanced C++ in a short period of time?

It's almost a contradiction in terms to suggest that someone can become an advanced practitioner of anything in a short period of time. Although your Java knowledge will help you learn C++ faster than someone who doesn't know any programming languages, do not be fooled by the superficial similarity of the two languages - they are very different beasts.

Here are a few possible starting points:

  1. Learn the language and libraries. I recommend the book Thinking in C++
  2. Learn how to use the language effectively - there are many more ways to misuse C++ than Java. I recommend Effective C++ and More Effective C++ to help you along this path.
  3. Spend about 5 years practicing, reading, learning from colleagues etc.
  4. Voila, now you are an advanced user :)

Aside:

Some other respondents have recommended Bjarne Stroustrup's book. Personally I think this is C++'s equivalent of the JLS. In other words, a great resource for getting definitive answers about the language "from the source", but very weak from the POV of language pedagogy.

Don
Apart from Scott Mayers' books I strongly recommend Herb Sutter's Exceptional C++ and More Exceptional C++. :)
Prasoon Saurav
I actually still recommend the old Annotated Reference Manual from Stroustrup - it's based on an out of date standard, but it explains a lot of the decisions that went into the language. Knowing this stuff helps you understand what the language is likely to be like in other situations.
Michael Kohne
@Michael Kohne: I never did read the ARM, but Stroustrup's book "Design and Evolution" explains a lot of decisions, in addition to being an excellent book on language design in the first place.
David Thornley
I'm not bad-mouthing Bjarne's books per se. I just don't think they're a very good entry point into learning the language.
Don
+4  A: 

There are several gotchas you will run into when moving from Java to C++. As others have already said, many seemingly simple constructs can lead to undefined behaviour. Here's bunch of things to look out for:

Pointers

  1. Pointers must be dereferenced to get at their contents using the . operator. To get at the contents of a pointer directly (without dereferencing), you must use the -> operator. Since everything is essentially a pointer in Java, this issue never arises.

  2. You can increment a pointer past the end of an array and the compiler will not complain in the slightest, but this leads to undefined behaviour. In Java, analogous code leads to an ArrayIndexOutOfBoundsException.

Object oriented programming

  1. Not everything derives from a single class, as in Java. If you want a function that can arguments of any type, you have the choice of either using templates (preferred) or the dreaded void* pointers.

  2. Even if you have a heirarchy, you cannot simply assign an object of a child class to a parent class variable. Doing this leads to an annoying and possibly hard to debug problem called object slicing. To do Parent obj = new Child() as in Java, you would have to make obj a pointer to a parent object. Parent *obj = new Child().

  3. Virtual vs. non-virtual inheritance. All inheritance in Java is virtual. I'm not going to go into the details of virtual inheritance here, but suffice to say that you can get problems similar in type to object slicing with things like parent class methods being called where you expect child class methods.

  4. The default access modifier for class fields and methods in C++ is private rather than "package private" as in Java. The default access modifier for struct fields and methods is public.

Functions

  1. C++ supports two types of function call semantics: call by value and call by reference. Java only supports call by value. This is something that can quite easily trip you up.

Templates/Generics

  1. C++ supports generic functions as well as generic classes. Java only supports generic classes.

Memory management

  1. C++ is not garbage collected. This means that you have to be very careful about managing memory. Orphaned references will not magically disappear as in Java, but will cause your program to leak memory.

  2. C++ has a delete keyword to pair with new. Both these can only assign or delete to a pointer. On deleteing a pointer, the object's destructor (if present) is called. Java has no concept of a destructor (the finalize() method is vaguely analogous but is not a destructor).

Operator overloading

  1. C++ has this. Java doesn't.

This is by no means an exhaustive list, so hopefully you can see that the two languages are actually quite different. You will have to learn C++ more or less from scratch from a good book, though you might be able to pick it up quite quickly, being an experienced Java programmer.

EDIT: You asked what "undefined behaviour" means in the context of C++. It means that the code can do anything at all. It might run fine. It might crash the program. If it writes to an executable page by mistake, there is even a small but finite possibility that it could erase your hard disk (though most modern OSes should prevent this).

Chinmay Kanchi
Great post. Another thing is that in Java you are provided a platform that has nearly everything from Collections to a UI. And most programmers will stick to the stock APIs from Sun (for example generally you'd just use the Sun Collections). In C++, you get a synax and a compiler. You get some core libraries but they really don't compare to the wealth that Sun provides. That is the hard part. Going from the mentality of "Sun provides it" to "crap I gotta roll my own" (or get it from Boost).
tmeisenh
Yes, that's a good point. It can often be hard to choose the right library in C++, while for most things, Java has a "batteries included" approach.
Chinmay Kanchi
Thank you very much. This is very helpful indeed.
piggles
+1  A: 

If you're making the switch to C++ from Java, you'll need to get very familiar with pointers and all the trouble (joy) they can cause. Perhaps if you feel that you'd like something to boost your confidence why not take a look at static code analysis. There's a good SO thread about free versions that can help you catch errors your compiler may not find. I find these tools to be a good "guide" for anyone, even experienced C++ developers. They get you thinking ahead of time about code.

wheaties
+4  A: 

Here's some ideas you'll have to pick up.

Undefined behavior. Java nails down all sorts of behavior, and C++ doesn't. To be good at C++, you need to avoid undefined behavior.

RAII. Java garbage-collects memory, and has constructs like try...finally so you can write cleanup routines. In C++, resources should be allocated in classes that clean up in their destructor.

Less inheritance. In Java, all objects inherit from one class, and data structures operate on that basis. In C++, inheritance hierarchies are normally much shallower, and data structures are largely done with templates. You do need to understand templates.

Stack vs. Heap. In Java, classes are dynamically allocated, and standalone primitives are lexically scoped. C++ is much looser, which means that it's necessary to have explicit pointers and separate operators for referencing class members depending on whether they're designated by pointers or not.

There's lots of other differences, but they typically aren't as important (most people don't find it necessary to overload most operators) or are easier to pick up (differences in argument passing).

Probably the fundamental philosophical difference is that Java was designed to avoid language structures that are easy to get wrong, while C++ was designed to have powerful language features with the knowledge that they would be misused. Therefore, C++ has explicit multiple inheritance and user-definable operator overloading. C++'s typing system is intentionally weaker than Java's, to facilitate low-level programming, even though it makes it easier to mess up.

David Thornley
Hmm, out of curiosity, how do you figure C++'s typing system is weaker than Java's? I'd have said it was more powerful. Java's type system can't handle something as simple as `vector<int>` without loss of type information. And of course, if we include metaprogramming, C++'s type safety is taken to a whole other level. I'm not trying to prove you wrong though, just curious what you consider stronger about Java's type system.
jalf
In C++, there are trivial ways to shuffle bytes around to make larger data objects (`union` and `reinterpret_cast` come to mind). The pesky C-style cast (which I'd ban if I could) makes that easy to type and hard to find. When I first learned Java, there weren't such facilities, and IIRC the JVM wasn't set up to allow them.
David Thornley