www.freeOnlineBooks.tk
part of www.asadali.tk
Download Books for Free
Read Books OnlineThe C++ Casting Operators | 417
Why C-Style Casts Are Not Popular with
Some C++ Programmers
Type safety is one of the mantras that C++ programmers swear by when singing praises
to the qualities of this programming language. In fact, most C++ compilers won't even
let you get away with this:
char pszString = ‘Hello World!*;
int* pBuf = pszString; —// error: cannot convert char* to unsigned char*
..-and quite rightfully so!
Now, C++ compilers still do see the need to be backward compliant to keep old and
legacy code building, and therefore automatically allow syntax such as.
int* pBuf = (int*}pszString; // Cast one problem away to create a bigger one!
However, C-style casts actually force the compiler to interpret the destination as a type
that is very conveniently of the programmer's choice—a programmer who in this case
did not bother thinking that the compiler reported an error in the first place for good rea-
son, and simply muzzled the compiler and forced it to obey. This, of course, does not go
well down the throats of C++ programmers who see their type safety being compromised
by casts that force anything through.
The C++ Casting Operators
Despite the disadvantages of casting, the concept of casting itself cannot be discarded.
In many situations, casts are legitimate requirements to solve important compatibility
issues. C++ additionally supplies a new casting operator specific to inheritance-based
scenarios that did not exist with C programming.
The four C++ casting operators are
| static_cast
™ dynamic_cast
| reinterpret_cast
™ const_cast
14
The usage syntax of the casting operators is consistent:
destination_type result = cast_type (object_to_be_casted);418
LESSON 14: Casting Operators
Using static_cast
static_cast is a mechanism that can be used to convert pointers between related types,
and perform explicit type conversions for standard data types that would otherwise hap-
pen automatically or implicitly. As far as pointers go, static_cast implements a basic
compile-time check to ensure that the pointer is being cast to a related type. This is an
improvement over a C-style cast that allows a pointer to one object to be cast to an
absolutely unrelated type without any complaint. Using static_cast, a pointer can be
up-casted to the base-type, or can be down-casted to the derived type, as the following
code-sample indicates.
CBase* pBase = new CDerived (); = // construct a CDerived object
GDerived* pDerived = static _cast(pBase); —// ok!
{/ Cunrelated is not related to CBase via any inheritance hierarchy
GUnrelated* punrelated = static_cast(pBase); // Error
[/The cast above is not permitted as types are unrelated
However, note that static_cast verifies only that the pointer types are related. It does
not perform any runtime checks. So, with static_cast, a programmer could still get
away with this bug:
GBase* pBase = new CBase ();
CDerived* pDerived = static_cast(pBase); // Still no errors!
Here, pDerived actually points to a partial CDberived object because the object being
pointed to is actually a CBase() type. Because static_cast performs only a compile-time
check of verifying that the types in question are related and does not perform a runtime
check, a call to pDerived->SomeDerivedClassFunction() would get compiled, but
probably result in unexpected behavior during runtime.
Apart from helping in up-casting or down-casting, static_cast can in many cases help
make implicit casts explicit and bring them to the attention of the programmer or reader:
double dPi = 3.14159265;
int nNum = static_cast(dPij; // Making an otherwise implicit cast, explicit
In the preceding code, nNum = dPi would have worked as well and to the same effect.
However, using a static_cast brings the nature of conversion to the attention of the
reader and indicates (to someone who knows static_cast) that the compiler has per-
formed the necessary adjustments based on the information available at compile-time to
perform the required type-conversion.