C++ has several different cast operators that are used to access memory objects and each of these has differences in how they operate. In order to understand casting in C++ you need to understand the differences between these different casting methods and why you would use one or the other.
However first you must understand two fundamental differences between Java and C++ when it comes to how variables and objects are allocated and stored in memory.
The most fundamental difference between the two languages is the compile target for the two languages. Java is compiled into byte code and runs on a virtual machine. C++, most often, is compiled into native machine code and runs on the actual hardware using the hardware facilities such as CPU registers.
I used the caveat of "most often" for C++ because there are compilers, the Microsoft Visual Studio has such an option, that will generate byte code that runs on a virtual machine. However in most instances C++ is compiled to native, hardware machine code.
The second major difference between the two is how objects and variables and classes are stored and managed, how assignment works, and what kinds of information is available at runtime about the objects and variables and classes.
Java has a central memory store where objects are allocated with the new
operator. This means that a Java variable is not a physical storage area containing the object but rather a physical storage area that contains a reference which points to the actual storage area in the central memory store.
This central storage area contains not only the memory area for the actual objects but also information about the classes from which the objects are instantiated. In other words much of the type information available in the source code at compile time is also available to the virtual machine in which the program is running allowing the virtual machine to determine if a cast is valid at runtime when the conversion is being done.
C++ variables are memory areas where the value of the variable or object is actually stored. C++ has pointer variables which contain the address of the memory area where an object is stored and it has reference variables which contain a reference to the address of the memory area where an object is stored. However when you are accessing a C++ object or variable with the name of the object or variable, you are accessing the memory area of the object directly and not through a reference the way it is done in Java.
So an assignment statement in Java which assigns one object to another is really just making a copy of the reference rather than the actual object. This is why after doing an assignment you now have two variables pointing to the same thing. An assignment statement in C++ which assigns one object to another is making a copy of the actual object itself into another memory area which results in two copies of the same object.
The C++ language and compilers are designed to do validity checking when the source code is compiled and to remove much of the overhead involved in the checking that the Java virtual machine does. So the C++ compiler strips away most of the class information when it compiles the source code. There is the Runtime Type Identification option that can be used however there is additional overhead involved with using that (see How expensive is RTTI? ) and since C++ is running native on the hardware, there is no virtual machine that is using that information to decide as to the validity of operations.
Over the years C++ has improved the ability of the programmer to write source code which allows the compiler to catch typical types of mistakes. The changes in the cast operators and the addition of several types of cast operators was one of those improvements to address an area where it is easy to make a mistake that can cause problems yet be difficult to debug.
For further details concerning the different types of C++ casts see the following:
When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?
Regular cast vs. static_cast vs. dynamic_cast
dynamic_cast and static_cast in C++
Why use static_cast<int>(x) instead of (int)x?