1242.2 Langage C++ - 2025-2026
1. Introduction
2.
3.
4.
5.
6. RTTI
Les conversions (cast) peuvent être faites par des mots-clés dédiés
Syntaxe
Exemple
int i = 100;
auto c = static_cast<char>(i); // int -> char
auto f = 100.0f;
i = static_cast<int>(f); // float -> int
class Base{};
class Deri : public Base{};
auto d = new Deri;
auto b = static_cast<Base*>(d); // Deri* -> Base*
char c = 10; // 1 byte
int *p = (int*)&c; // 4 bytes
*p = 5; // run-time error: stack corruption
int *q = static_cast<int*>(&c); // compile-time error
auto f = 99.0f;
auto pf = &f;
auto d = 99.0;
auto pd = &d;
pd = static_cast<double*> (pf); // ⛔ error
pd = reinterpret_cast<double*>(pf); // ✅ ok
*aucune donnée n'est physiquement modifiée, ce n'est qu'une indication pour le compilateur
int i = 99;
auto ptr = reinterpret_cast<char*>(i); // int -> char*
auto ref = reinterpret_cast<char&>(i); // int -> char&
auto pf = reinterpret_cast<float*>(pd); // double* -> float*
Utile pour scanner de la mémoire (scanner un range de
class A{};
const A *cptr;
auto ptr = const_cast<A*>(cptr); // const A* -> A*
A a;
const A &cref = a;
auto ref = const_cast<A&>(cref); // const A& -> A&
Opérateur peu utile, car :
- la conversion non-const ⇒ const est implicite
- la conversion const ⇒ non-const relève souvent d'une erreur de conception
- le qualificatif
Il est utilisé pour supprimer la constance des références et des pointeurs qui se réfèrent à quelque chose qui, à la base, n'est pas const
Les seules possibilités de conversion sont
⇒ elle doit comporter au moins une fonction membre virtuelle
⇒ être manipulée au moyen d'un pointeur ou d'une référence
Ce type de cast est dynamique (effectué à l'exécution), et est susceptible d'échouer :
⇒ renvoie
⇒ lève une exception
Product *products[100];
for (auto i = 0; i < 100; ++i)
{
auto ptrLiquor = dynamic_cast<Liquor*>(products[i]);
if (ptrLiquor != nullptr)
{
std::println("{}", ptrLiquor->degree());
}
else
{
std::println("{}", products[i]->name());
}
}
- La fonction que l'on écrit ne travaille en fait pas sur la classe de base, mais seulement sur certaines classes dérivées bien identifiées
- Polymorphisme dynamique pas exploité (fonctions virtuelles)
- Polymorphisme statique pas exploité (utilisation de templates, surcharges)
- Hiérarchie de classes mal structurée
Permet de déterminer le type d'une variable à l'exécution (runtime)
Le mécanisme RTTI contient :
- Le mot-clé de conversion
- L'opérateur
⇒ utilisé pour vérifier le type d'un objet à l'exécution
typeid(int).name() // ⇒ i
typeid(float).name() // ⇒ f
typeid(2+2.00).name() // ⇒ d
typeid(ptri).name() // ⇒ Pi
typeid(ptrf).name() // ⇒ Pf
typeid(refd).name() // ⇒ d
AAA a;
typeid(a).name() // ⇒ Z4mainE3AAA
class Animal { public: virtual ~Animal(){}};
class Mammal : public Animal {};
class Dog : public Mammal {};
class Poodle : public Dog {};
int main()
{
Animal *ptr = new Poodle;
typeid(ptr).name(); // ⇒ P6Animal
typeid(*ptr).name(); // ⇒ 7Poodle
typeid(*ptr) == typeid(Dog); // ⇒ false
typeid(*ptr) == typeid(Poodle); // ⇒ true
return 0;
}
if (typeid(*ptr) == typeid(Dog)) {...}
if (auto c = dynamic_cast<Dog*>(ptr)) {...}