Cast | Conversion | Reinterpretation | Upcast | Downcast | Type qualifier |
---|---|---|---|---|---|
Implicit | Yes | Yes | |||
Static | Yes | Yes | Yes | ||
Dynamic_Cast | Yes | Yes | |||
Const_cast | Yes | ||||
Reinterpret_cast | Yes | Yes | Yes | ||
Legacy C Cast | Yes | Yes | Yes | Yes | Yes |
Conversion = Changement de type = Reorganisation des bits pour garder la même valeur. Ch
int a;
double b = a; // Implicit conversion cast + implicit promotion
double c = (double) a; // Explicit conversion cast
int d = (int) n; // Implicit demotion
Reinterpretation = conversion identitaire = Changement de type d'adresse = le codage des bits n'est pas modifié void * est le type le plus générale, moins précis
float a;
void b = &a; // Implicit reinterpretation cast
void * b = (void *) a; // Implicit reinterpretation cast
void * d = &a; // Implicit promotion
int * e = d; // Implicit demotion -> Bad !
int * f = (int *) d; // Explicit demotion
The reinterpretation needs to be explicit otherwise does not compile.
int const * d = 1;
int * e = d; // Implicit demotion -> WARNING, doesn't compile
int * e = (int *)d; // Explicit demotion
The reinterpretation needs to be explicit otherwise does not compile. Une classe parent est plus générale que la classe enfant.
En C++, on utilise static_cast pour downcast, upcast and conversion dans la même hierarchie de classes.
int a = 42;
double b = a; // Implicit promotion
int * e = static_cast<int>(b); // Explicit demotion
Le cast se fait à l'execution. De plus il faut qu'il y ait une méthode dans la classe. (Polymorphisme par sous-typage)
class Parent {public : virtual ~Parent(void) {}};
class Child1 : public Parent {};
class Child2 : public Parent {};
Child1 a;
Parent *b = &a; // Implicit upcast
try
{
Child1 *c = dynamic_cast<Child1 *>(b);
Child2 & d = dynamic_cast<Child2 &>(*b); -> error
}
catch (std::bad_cast &bc)
{
cout << "Cast error" << endl;
}
Le cast le plus permissif. Il convertit anyway.
float a = 420.042f;
void * b = & a;
int * c = reinterpret_cast<int *> (b); -> ok
int & d = reinterpret_cast<int &> (b); -> ok
Le cast entre type constant et type mutable. = cast de qualifieur de type
float a = 420.042f;
void * b = & a;
int * c = reinterpret_cast<int *> (b); -> ok
int & d = const_cast<int &> (b); -> ok
Allow to implicit cast thanks to the class.
class foo {
public :
operator float() {return _value ;}
operator int() {return static_cast<int>(_value) ;}
private :
float _value;}
foo a(420.024f);
float b = a;
int c = a;
No conversion is allowed in the constructor.