Professional C__ - Marc Gregoire [147]
Another use for the static_cast is to perform downcasts in an inheritance hierarchy. For example:
class Base
{
public:
Base() {};
virtual ~Base() {}
};
class Derived : public Base
{
public:
Derived() {}
virtual ~Derived() {}
};
int main()
{
Base* b;
Derived* d = new Derived();
b = d; // Don't need a cast to go up the inheritance hierarchy
d = static_cast Base base; Derived derived; Base& br = derived; Derived& dr = static_cast return 0; } Code snippet from Casts\StaticCast.cpp These casts work with both pointers and references. They do not work with objects themselves. Note that these casts with static_cast do not perform run-time type checking. They allow you to convert any Base pointer to a Derived pointer or Base reference to a Derived reference, even if the Base really isn’t a Derived at run time. For example, the following code will compile and execute, but using the pointer d can result in potentially catastrophic failure, including memory overwrites outside the bounds of the object. Base* b = new Base(); Derived* d = static_cast To perform the cast safely, with run-time type checking, use the dynamic_cast explained in a following section. static_casts are not all-powerful. You can’t static_cast pointers of one type to pointers of another unrelated type. You can’t static_cast directly objects of one type to objects of another type. You can’t static_cast a const type to a non-const type. You can’t static_cast pointers to ints. Basically, you can’t do anything that doesn’t make sense according to the type rules of C++. reinterpret_cast The reinterpret_cast is a bit more powerful, and concomitantly less safe, than the static_cast. You can use it to perform some casts that are not technically allowed by C++ type rules, but which might make sense to the programmer in some circumstances. For example, you can cast a pointer type to any other pointer type, even if they are unrelated by an inheritance hierarchy. This is commonly used to cast a pointer to a void* and back. Similarly, you can cast a reference to one type to a reference to another type, even if the types are unrelated. Here are some examples: class X {}; class Y {}; int main() { X x; Y y; X* xp = &x; Y* yp = &y; // Need reinterpret cast for pointer conversion from unrelated classes // static_cast doesn't work. xp = reinterpret_cast // Need reinterpret cast for pointer conversion from unrelated pointers void* p = reinterpret_cast xp = reinterpret_cast // Need reinterpret cast for reference conversion from unrelated classes // static_cast doesn't work. X& xr = x; Y& yr = reinterpret_cast return 0; } Code snippet from Casts\ReinterpretCast.cpp In theory, you could also use reinterpret_cast to cast pointers to ints and ints to pointers, but this is considered erroneous programming, because on many platforms (especially 64-bit platforms) pointers and ints are of different sizes. For example, on a 64-bit platform, pointers will be 64 bit, but integers could be 32 bit. Casting a 64-bit pointer to a 32-bit integer will result in losing 32 critical bits! You should be very careful with the reinterpret_cast because it allows you to do conversions without performing any type checking. dynamic_cast The dynamic_cast provides a run-time check on casts within an inheritance hierarchy. You can use it to cast pointers or references. dynamic_cast checks the run-time type information of the underlying object at run time. If the cast doesn’t make sense, dynamic_cast returns a null pointer (for the pointer version) or throws a bad_cast exception (for the