Comment utiliser le Dynamic Cast en C++
Cet article présente plusieurs méthodes d’utilisation de la fonte dynamique en C++.
Utilisez dynamic_cast
pour convertir un pointeur de classe de base en dérivé
dynamic_cast
permet au programmeur de convertir les pointeurs et les références aux classes à travers la hiérarchie d’héritage. Par exemple, le pointeur de classe de base peut être transformé en un pointeur de classe dérivé et permettre au programmeur d’appeler des fonctions de membres de classe dérivées.
La fonction dynamic_cast
fait partie de la fonction Run-Time Type Information (RTTI) qui fournit un moyen d’accéder au type d’un objet au moment de l’exécution plutôt qu’au moment de la compilation.
Notez que dynamic_cast
ne peut pas être utilisé pour convertir entre les types primitifs comme int
ou float
. De plus, on ne doit utiliser dynamic_cast
que lorsque la classe de base contient au moins une fonction membre virtuelle. Dans l’exemple suivant, nous déclarons un nouveau pointeur de classe Base
et le lançons dans le nouveau pointeur de la classe Derived
. Puisque dynamic_cast
retourne un pointeur nul, si le cast ne réussit pas, nous pouvons mettre l’expression dans la déclaration if
comme condition.
#include <iostream>
#include <typeinfo>
using std::cout;
using std::endl;
struct Base {
virtual ~Base() = default;
};
struct Derived : public Base {};
int main() {
Base *bp = new Derived;
if (Derived *dp = dynamic_cast<Derived *>(bp)) {
cout << "Successful cast - can use the pointer to 'Derived' object dp"
<< endl;
}
delete bp;
return EXIT_SUCCESS;
}
Production :
Successful cast - can use the pointer to 'Derived' object dp
Le programmeur peut accéder en toute sécurité à l’objet dans la section if
et appeler les méthodes des membres de la classe Derived
si nécessaire. Notez cependant, que puisque nous lançons le type de classe Derived
vers Base
, à la 13ème ligne, nous spécifions Derived
après le new
opérateur car le code suivant produirait un échec :
#include <iostream>
#include <typeinfo>
using std::cout;
using std::endl;
struct Base {
virtual ~Base() = default;
};
struct Derived : public Base {};
int main() {
Base *bp = new Base;
if (Derived *dp = dynamic_cast<Derived *>(bp)) {
cout << "Successful cast - can use the pointer to 'Derived' object dp"
<< endl;
}
delete bp;
return EXIT_SUCCESS;
}
L’autre partie de la fonctionnalité RTTI est l’opérateur typeid
, qui retourne le type de l’expression donnée. Il peut être utilisé pour comparer des types d’expressions multiples, comme le montre l’exemple de code suivant. Notez que l’en-tête <typeinfo>
doit être inclus lorsque vous utilisez l’opérateur typeid
.
#include <iostream>
#include <typeinfo>
using std::cout;
using std::endl;
struct Base {
virtual ~Base() = default;
};
struct Derived : public Base {};
int main() {
Base *bp = new Derived;
if (Derived *dp = dynamic_cast<Derived *>(bp)) {
cout << "Successful cast - can use the pointer to 'Derived' object dp"
<< endl;
if (typeid(*bp) == typeid(*dp)) {
cout << "bp and dp are of same type" << endl;
}
}
delete bp;
return EXIT_SUCCESS;
}
Production :
Successful cast - can use the pointer to 'Derived' object dp
bp and dp are of same type
Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.
LinkedIn Facebook