Are there any good guides online to prime an advanced Java user for advanced C++ in a short period of time?
Its not specific to Java programmers, but I find this SO thread very helpful.
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.
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.
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:
- Learn the language and libraries. I recommend the book Thinking in C++
- 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.
- Spend about 5 years practicing, reading, learning from colleagues etc.
- 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.
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
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.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
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.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 makeobj
a pointer to a parent object.Parent *obj = new Child()
.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.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 ispublic
.
Functions
- 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
- C++ supports generic functions as well as generic classes. Java only supports generic classes.
Memory management
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.
C++ has a
delete
keyword to pair withnew
. Both these can only assign or delete to a pointer. Ondelete
ing a pointer, the object's destructor (if present) is called. Java has no concept of a destructor (thefinalize()
method is vaguely analogous but is not a destructor).
Operator overloading
- 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).
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.
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.