Il y a cinq manières différentes de lancer des variables. Il y a un chevauchement entre eux, en particulier avec la distribution C-style et toutes les autres versions, mais chacune a son utilisation. Il est bon de les apprendre tous, afin que vous puissiez utiliser la meilleure distribution pour votre besoin particulier plutôt que d'utiliser une distribution qui fonctionne. Si vous avez besoin d'une référence rapide, je recommande ce post sur StackOverflow.
Je ne parle pas du casting implicite ici pour la simple raison que c'est un concept de base avec un nombre presque infini de variations. Si j'écris float f = 10;
J'ai implicitement jeté un entier sur un float et stocké son résultat dans f. Vous pouvez également implicitement convertir un objet de type B en pointeur sur sa classe de base A à l'aide de l'opérateur address-of ou sur une référence à sa classe de base A en effectuant une affectation normale..
const_cast
L'opérateur const_cast peut ajouter et supprimer const et volatile. Son utilisation pour ajouter l’un ou l’autre de ces attributs est acceptable. C'est rare, mais si vous le faites, vous pouvez.
Sa capacité à supprimer const est quelque chose que vous ne devriez jamais utiliser dans un programme C ++, sauf lorsque vous devez appeler une fonction du langage C qui ne respecte pas la valeur de const-correct, mais ne modifie pas du tout l'objet. Si une fonction a un paramètre const et en rejette la const-ness en utilisant const_cast, la fonction rompt le contrat implicite selon laquelle elle ne modifiera pas le paramètre. C'est donc à vous, en tant qu'auteur de cette fonction, de vous assurer que vous n'allez pas modifier l'objet; sinon, vous ne devriez pas utiliser const pour le paramètre car vous allez modifier l'objet.
Si vous avez besoin d'utiliser const_cast et un autre opérateur de conversion sur le même objet, utilisez const_cast en dernier, car la suppression de const-ness d'un objet pourrait permettre que des modifications non intentionnelles aient lieu si vous utilisiez une distribution ultérieure..
static_cast
L'opérateur static_cast est utile pour le casting:
En général, chaque fois que vous convertissez des types fondamentaux en d'autres types fondamentaux, utilisez static_cast. En règle générale, static_cast doit être votre premier choix d'incantations, car il effectue toutes les vérifications qu'il peut effectuer au moment de la compilation. Vous n'avez donc pas ajouté de vérification à l'exécution pour ralentir votre programme..
diffusion_dynamique
L'opérateur dynamic_cast est utile pour la diffusion via l'héritage virtuel. static_cast peut convertir une classe dérivée en une classe de base, que l'héritage soit virtuel ou non. Supposons toutefois que vous receviez un objet de type A, mais que vous sachiez qu'il s'agissait en fait d'un objet de type B et que B héritait virtuellement de A. Si vous souhaitez rediffuser cet objet en B pour qu'il utilise des fonctions membres uniquement B fournit, vous devez utiliser dynamic_cast.
Quelques choses à propos de dynamic_cast. Premièrement, cela ne fonctionne que sur les conversions point à point ou référence à référence. Deuxièmement, il ne peut pas réellement lancer un objet d'un A vers un B si l'objet n'est pas, en fait, un B (ou un type dérivé de B). Un pointeur à pointeur dynamic_cast qui échoue renvoie la valeur null. Un échec de référence à référence jette un std :: bad_cast
exception.
réinterpréter_cast
L'opérateur reinterpret_cast est une conversion directe avec très peu de bonnes utilisations. La plupart de ses opérations donnent des résultats non définis. En pratique, cela signifie que vous devriez lire la documentation du fournisseur du compilateur avant de l’utiliser pour quoi que ce soit..
Une utilisation, comme nous l’avons vu dans StorageDurationSample
, est de convertir un pointeur en un type entier suffisamment grand pour le contenir. Cela donne l'adresse de la mémoire du pointeur, ce qui peut être utile pour les opérations de débogage et de traçage où vous pouvez vider des données dans des fichiers journaux et créer des vidages mémoire, mais il peut ne pas être possible d'exécuter un débogueur facilement. Vous verrez qu'il est parfois légitimement utilisé à d'autres fins, mais en général, il devrait être considéré comme une distribution de dernier recours (à l'exception d'une distribution de style C, qui vient après reinterpret_cast)..
La distribution de style C, (par exemple., auto someData = (SomeType) dataOfSomeOtherType;
) n'est pas votre ami. Vous le connaissez sans doute depuis C #, où il est très utile. En C #, si vous essayez d'effectuer un transtypage à l'aide de cette syntaxe et que le transtypage n'est pas valide, vous allez générer une exception InvalidCastException. Cela est dû au fait que le CLR garde la trace des types de tout ce que vous avez créé et détecte les mauvais casting..
C ++ ne vérifie pas si votre conversion de style C est valide, en supposant qu'il compile, bien sûr. C ++ suppose simplement que c'est le cas. Si la distribution est mauvaise et que vous avez de la chance, votre programme plantera immédiatement. Sinon, vous vous retrouverez avec des données dans un état inconnu, qui sera certainement corrompu de manière subtile et insidieuse..
En outre, contrairement aux autres moulages, que vous pouvez facilement repérer en cherchant _cast<, C-style casts do not stick out. When you're scanning lots of code quickly, parentheses wrapped around text looks as much like a function call as it does a cast operation. You could use a regular expression search for this in Visual Studio 2012: \(.*\)[A-Za-z]. Even so, you are still forgoing all the benefits and protections of the other casts.
La seule chose qu'une conversion de style C puisse faire, contrairement aux autres distributions, est de convertir un objet dans l'une de ses classes de base d'héritage protégé ou privé. Vous ne devriez vraiment pas faire cela car, si vous avez besoin d'un héritage public, vous devez utiliser un héritage public..
En bref, n'utilisez pas de fonte de style C.
Il existe un exemple, CastingSample, qui illustre les nombreux types de transtypage possibles. Il est inclus avec le code source de cette série. Par souci de brièveté, je l'omets ici.
Dans cet article, nous avons abordé le casting en C ++ et j'espère qu'il est clair que vous ne devriez pas utiliser de casting en style C. Le prochain article zoom sur les chaînes en C++.
Cette leçon représente un chapitre de C ++ Succinctly, un eBook gratuit de l’équipe de Syncfusion..