In your example, the dynamic_cast doesn't affect the ptrA at all. It essentially allows you to get a pointer to a B object in ptrB. If you were to print out the address values of ptrA and ptrB, you would likely get the same address even. (Note: This might not ALWAYS be the case, such as if you use multiple inheritance...)
After you do the cast , the difference between ptrA and ptrB will be that with ptrB you can access public methods/members that are specific to B, whereas with ptrA, you can only access the methods/members that are specific to A. dynamic_cast will use run-time type information to ensure that A can be cast to B.
const_cast is something that generally isn't a good practice to use. You can use that to cast away the const status of an object. The ONLY time it should be used, is if you have a function that takes a non-const parameter and you KNOW that it won't modify that value.
Here's some example code:
Code:
#include <iostream>
int DoSomething(int *p);
int main()
{
const int i = 10;
int *p;
// Here it's ok to use the const_cast, we know that
// DoSomething doesn't modify the value
DoSomething(const_cast<int*>(&i));
// This is dangerous, because we are modifiying a const!
p = const_cast<int*>(&i);
*p = 20;
std::cout << i << std::endl;
}
int DoSomething(int *p)
{
// Doesn't modify the value of p, just returns it
return *p;
}
Result:
Code:
$ g++ -o ugh ugh.cpp
$ ./ugh
10
Note: The value of i wasn't changed as we might expect....
There is also static_cast, which is generally used to cast to naturally similar types. Like float to int, int to float, etc.
reinterpret_cast can generally be used to cast to dissimilar types. It can be used to cast one pointer type to any other pointer type. This also can be inherently unsafe. When possible, use the other casting types. I've used this to cast things like void* to char*, etc...