Vous êtes sur la page 1sur 14

CASTING IN C++

INTRODUCTION
 A cast is a special operator that forces one data
type to be converted into another. As an operator,
a cast is unary and has the same precedence as
any other unary operator.
 The most general cast supported by most of the
C++ compilers is as follows:
 (type) expression
CASTING OPERATORS
 Static casts
 Const Casts

 Dynamic Casts

 Reinterpret Casts
STATIC CASTS
 Standard conversion. For instance: from short to
int or from int to float.
 User defined conversions (Class conversions.)

 Conversion from derived class to base class.


EXAMPLES
int a = 5; enum my_numbers { a=10, c=100,
int b = 2; e=1000 };
double out; const my_numbers b =
static_cast<my_numbers> (50);
// typecast a to double
const my_numbers d =
out =
static_cast<my_numbers> (500);
static_cast<double>(a)/b;

Note: We add some new values (b and


d). These are type-cast from int to
enum.
REINTERPRET_CAST

The reinterpret_cast is used for casts that are not safe:


 Between integers and pointers
 Between pointers and pointers
 Between function-pointers and function-pointers
 For instance the typecast from an integer to a
character pointer:
 char *ptr_my = reinterpret_cast<char *>(0xb0000);
Note: the example above uses a fixed memory location.
 A reinterpret_cast can not be used to cast a const
object to non-const object. For instance:
 char *const MY = 0; // This is not valid because MY is a
const!!
 int *ptr_my = reinterpret_cast<int *>( MY);
CONST_CAST

 The only way to cast away the const properties of


an object is
void a(Person* b);
int main()
{
const Person *ptr_my = new Person("Joe");
a( const_cast<Person *>(ptr_my) );
}
 The use of const_cast on an object doesn’t
guarantee that the object can be used (after the
const is cast away.) Because it is possible that the
const-objects are put in read-only memory by the
program.
CONTI…
 The const_cast can not be used to cast to other data-
types, as it is possible with the other cast functions.
int a;
const char *ptr_my = "Hello";
a = const_cast<int *>(ptr_my);
a = reinterpret_cast<const char*>(ptr_my);
a = reinterpret_cast<int *>(const_cast<char *>(ptr_my) );
 casting from const char * to int * isn’t very good
 The first statement (const_cast) will give an error,
because the const_cast can’t convert the type. The second
statement (reinterpret_cast) will also give an error,
because the reinterpret_cast can’t cast the const away.
The third statement will work (mind the note. It is a
dirty trick, better not use it.)
DYNAMIC_CAST

 The dynamic_cast can only be used with pointers


and references to objects. It makes sure that the
result of the type conversion is valid and
complete object of the requested class. This is
way a dynamic_cast will always be successful if
we use it to cast a class to one of its base classes.
class Derived_Class: public Base_Class { };
Base_Class a;
Base_Class * ptr_a;
Derived_Class b;
Derived_Class * ptr_b;
ptr_a = dynamic_cast<Base_Class *>(&b);
ptr_b = dynamic_cast<Derived_Class *>(&a);
 The first dynamic_cast statement will work
because we cast from derived to base. The second
dynamic_cast statement will produce a
compilation error because base to derived
conversion is not allowed with dynamic_cast
unless the base class is polymorphic.
WHEN SHOULD STATIC_CAST, DYNAMIC_CAST,
CONST_CAST AND REINTERPRET_CAST BE
USED?
 Static_cast is the first cast you should attempt to use. It
does things like implicit conversions between types (such
as int to float, or pointer to void*), and it can also call
explicit conversion functions (or implicit ones). In many
cases, explicitly stating static_cast isn't necessary, but it's
important to note that the T(something) syntax is
equivalent to (T)something and should be avoided (more on
that later). A T(something, something_else) is safe,
however, and guaranteed to call the constructor.
 static_cast can also cast through inheritance hierarchies. It
is unnecessary when casting upwards (towards a base
class), but when casting downwards it can be used as long
as it doesn't cast through virtual inheritance. It does not do
checking, however, and it is undefined behavior
to static_castdown a hierarchy to a type that isn't actually
the type of the object.
 const_cast can be used to remove or add const to
a variable; no other C++ cast is capable of
removing it (not even reinterpret_cast). It is
important to note that modifying a
formerly constvalue is only undefined if the
original variable is const; if you use it to take
the const off a reference to something that wasn't
declared with const, it is safe. This can be useful
when overloading member functions based
on const, for instance. It can also be used to
add const to an object, such as to call a member
function overload.
 const_cast also works similarly on volatile,
though that's less common.
 dynamic_cast is almost exclusively used for handling
polymorphism. You can cast a pointer or reference to any
polymorphic type to any other class type (a polymorphic
type has at least one virtual function, declared or
inherited). You can use it for more than just casting
downwards -- you can cast sideways or even up another
chain. The dynamic_cast will seek out the desired object
and return it if possible. If it can't, it will return nullptr in
the case of a pointer, or throw std::bad_cast in the case of a
reference.
 dynamic_cast has some limitations, though. It doesn't work
if there are multiple objects of the same type in the
inheritance hierarchy (the so-called 'dreaded diamond') and
you aren't using virtualinheritance. It also can only go
through public inheritance - it will always fail to travel
through protected or private inheritance. This is rarely an
issue, however, as such forms of inheritance are rare.
 reinterpret_cast is the most dangerous cast, and
should be used very sparingly. It turns one type
directly into another - such as casting the value from
one pointer to another, or storing a pointer in an int,
or all sorts of other nasty things. Largely, the only
guarantee you get with reinterpret_cast is that
normally if you cast the result back to the original
type, you will get the exact same value (but notif the
intermediate type is smaller than the original type).
There are a number of conversions
that reinterpret_cast cannot do, too. It's used
primarily for particularly weird conversions and bit
manipulations, like turning a raw data stream into
actual data, or storing data in the low bits of an
aligned pointer.

Vous aimerez peut-être aussi