| ||||
auteurs : Aurélien Regat-Barrel, Laurent Gomila | ||||
Contrairement au C, les cast C++ sont effectués au moyen d'opérateurs spécifiques (mots-clés réservés). Le choix de ces opérateurs
dépend du type de cast, car le C++ différencie 4 types de conversion explicite. Tout d'abord, 3 opérateurs sont dédiés aux conversions
statiques (effectuées à la compilation) :
* static_cast : entre types de même famille. Il s'agit la plupart du temps d'expliciter des conversions qui auraient pu être
effectuées de manière implicite, mais souvent avec un avertissement du compilateur.
* reinterpret_cast : entre types de familles différentes. Il s'agit simplement de dire au compilateur "je sais que je manipule une
donnée de type X, mais on va faire comme si elle était de type Y". De ce fait aucune donnée n'est physiquement modifiée, cet opérateur
de conversion n'est qu'une indication pour le compilateur.
* const_cast : entre un type donné constant et le même type avec / sans les qualificateurs const ou volatile. Cet opérateur est
rarement utilisé, car :
Le C++ supporte aussi un autre type de conversion : depuis une classe parent vers une classe enfant (downcasting) ou depuis une classe
parent vers une autre classe parent (crosscasting). La classe parent doit être à usage polymorphique,
autrement dit elle doit obligatoirement comporter au moins une fonction membre virtuelle, et être manipulée au moyen d'un pointeur ou d'une référence (la virtualité
implique l'utilisation de pointeurs ou de références, voir Que signifie le mot-clé virtual ?). Ce type de cast étant dynamique (effectué à
l'exécution), il est susceptible d'échouer et de lever une exception std::bad_cast dans le cas d'une conversion de références, ou de
renvoyer NULL dans le cas d'une conversion de pointeurs.
L'opérateur associé à ce cast est dynamic_cast :
dynamic_cast identifie à l'exécution le type réel de l'expression reçue au moyen des informations de type à l'exécution (RTTI).
Cette fonctionnalité doit donc être activée dans votre compilateur pour pouvoir utiliser dynamic_cast, ce qui n'est pas le cas par
défaut avec certains compilateurs (tel que VC++, voir l'option /GR).
Dernière remarque concernant dynamic_cast : celui-ci est souvent utilisé à tort, surtout par les débutants. Voir
Pourquoi l'utilisation du downcasting est-il souvent une pratique à éviter ?. Voir également Qu'est-ce que le cross-casting ?.
Si vous souhaitez tester votre maîtrise des casts C++, nous vous renvoyons à l'item n° 17 des GOTW (Guru Of The Week)
( http://www.gotw.ca/gotw/017.htm).
|
| ||
auteurs : Laurent Gomila, Aurélien Regat-Barrel | ||
On est souvent tenté d'utiliser l'opérateur de conversion dynamic_cast pour effectuer un downcasting
(voir Comment effectuer une conversion de type explicite (cast) ?), mais il s'agit fréquemment d'une erreur. Pourquoi ? Car conceptuellement parlant, on a en réalité
rarement besoin de connaître le type réel d'un objet que l'on manipule via sa classe de base. Si l'on se retrouve dans une telle
situation, c'est probablement que :
Le downcasting est donc à utiliser avec parcimonie, lorsque l'on n'a pas le choix ou que l'on sait exactement ce que l'on fait.
Par exemple dans le cas des plugin, ou encore lorsque l'on travaille avec un code, une bibliothèque ou une API qui ne connaîtrait (et donc
ne pourrait manipuler) que la classe de base d'une hiérarchie. Les classes dérivées étant écrites par le client, le downcasting est donc
une solution simple pour communiquer avec la bibliothèque en question. On peut également citer des implémentations de double-dispatching utilisant le downcasting (notamment dans la bibliothèque Loki).
Il faut donc toujours s'interroger sur l'utilisation que l'on fait de dynamic_cast : est-ce une nécessité, ou seulement un moyen pratique de
contourner une erreur de conception ?
|
| |||
auteur : Aurélien Regat-Barrel | |||
Le cross casting est une possibilité offerte par le C++ grâce à son support de l'héritage multiple. Dans l'exemple suivant :
un cast classique permet, à partir de C de convertir en A ou en B. Le cross casting consiste par exemple à obtenir une instance de B à
partir d'une instance de... A !
cet exemple fonctionne car il revient à faire :
Cette décomposition illustre pourquoi le recours à dynamic_cast est obligatoire (pour le downcasting).
Nous avons donc fait une conversion au travers de la hiérarchie d'héritage, d'où ce terme de cross casting.
Pour plus de précisions sur le cross-casting et ses applications, vous pouvez lire ce document : Cross Casting: The Capsule Pattern. |
Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2008 Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.