Casting en C

黄舟
黄舟original
2017-02-06 13:43:521904parcourir

Q : Qu'est-ce que la conversion de style C ? Que sont static_cast, Dynamic_cast et reinterpret_cast ? Quelle est la différence ? Pourquoi devrions-nous y prêter attention ?


A : Le sens de la conversion est de changer la représentation d'une variable en changeant le type de la variable en un autre type. Pour convertir un objet simple en un autre, vous utiliserez des opérateurs de conversion de type traditionnels.


Par exemple, pour convertir un pointeur en nombre à virgule flottante de type double en entier :

Code

int i;
double d;
i = (int) d;


ou :

i = int (d);


fonctionne bien pour les types simples avec des conversions définies standard. Cependant, de tels opérateurs de conversion peuvent également être appliqués sans discernement aux classes et aux pointeurs de classe. La norme ANSI-C définit quatre nouveaux opérateurs de conversion : 'reinterpret_cast', 'static_cast', 'dynamic_cast' et 'const_cast', qui sont destinés à contrôler la conversion de type entre les classes.


Code :

reinterpret_cast<new_type>(expression)
dynamic_cast<new_type>(expression)
static_cast<new_type>(expression)
const_cast<new_type>(expression)


1 réinterprétation_cast


reinterpret_cast Convertit un pointeur en pointeur d'autres types. Il permet également la conversion d'un pointeur en un type entier. vice versa. (Annotation : la valeur d'adresse spécifique du pointeur est-elle une valeur entière ?)


Cet opérateur peut convertir entre des types non liés. Le résultat de l’opération est simplement une copie binaire de la valeur d’un pointeur vers un autre pointeur. Le contenu pointé entre les types ne subit aucune vérification ou conversion de type. S'il s'agit d'une copie d'un pointeur vers un entier, l'interprétation du contenu dépend du système, donc toute implémentation n'est pas opportune. Un pointeur converti en un type entier suffisamment grand pour le contenir peut être reconverti en un pointeur valide.


Code :

class A {};
class B {};
A * a = new A;
B * b = reinterpret_cast<B *>(a);


reinterpret_cast traite toutes les conversions de type pointeur comme les conversions de type traditionnelles.


2 static_cast


static_cast permet des actions de conversion implicite arbitraire et de conversion inverse. (même s'il n'est pas permis d'être implicite)


signifie qu'il permet de convertir un pointeur de type sous-classe en un pointeur de type superclasse (c'est un pointeur implicite valide Conversion), et en même temps, peut également effectuer l'action inverse : convertir une classe parent en sa sous-classe. Dans ce dernier exemple, la cohérence de la classe parent convertie avec le type de destination n'est pas vérifiée.


Code :

class Base {};
class Derived : public Base {};
 
Base *a = new Base;
Derived *b = static_cast<Derived *>(a);


static_cast En plus des pointeurs de type opérationnel, static_cast peut également être utilisé pour effectuer l'affichage de la conversion des formules de définitions de types, et la conversion standard entre les types de base :


Code :

double d = 3.14159265;
int i = static_cast<int>(d);


3dynamic_cast


dynamic_cast est uniquement utilisé pour les pointeurs et les références à des objets. Lorsqu'il est utilisé avec des types polymorphes, il permet des conversions de types implicites arbitraires et vice versa. Cependant, contrairement à static_cast, dans ce dernier cas (remarque : le processus inverse de conversion implicite), Dynamic_cast vérifiera si l'opération est valide. Autrement dit, il vérifie si la conversion renverra un objet complet valide demandé.


La détection se produit au moment de l'exécution. Si le pointeur converti n'est pas un pointeur d'objet complet valide comme demandé, la valeur de retour est NULL.


Code :

class Base { virtual dummy() {} };
class Derived : public Base {};
 
Base* b1 = new Derived;
Base* b2 = new Base;
 
Derived* d1 = dynamic_cast<Derived *>(b1); // succeeds
Derived* d2 = dynamic_cast<Derived *>(b2); // fails: returns &#39;NULL&#39;


Si un transtypage de type est effectué sur un type référence et que cette conversion n'est pas possible, une exception bad_cast type est levée :


Code :

class Base { virtual dummy() {} };
class Derived : public Base { };
 
Base* b1 = new Derived;
Base* b2 = new Base;
 
Derived d1 = dynamic_cast<Derived &*>(b1); // succeeds
Derived d2 = dynamic_cast<Derived &*>(b2); // fails: exception thrown

4 const_cast


Ce type de conversion manipule l'attribut const de l'objet passé, soit en le définissant, soit en le supprimant :


Code :

class C {};
const C *a = new C;
 
C *b = const_cast<C *>(a);


Les trois autres opérateurs ne peuvent pas modifier la constance d'un objet. Remarque : 'const_cast' peut également modifier le qualificatif volatile d'un type.


Chacune des quatre formes cast de C est adaptée à un objectif spécifique


dynamic_cast est principalement utilisé pour l'exécution « Downcasting sécurisé », c'est-à-dire déterminer si un objet est un type spécifique dans une hiérarchie d'héritage. Il s’agit du seul transtypage qui ne peut pas être effectué avec l’ancienne syntaxe, et c’est le seul qui peut avoir un coût d’exécution important.

static_cast peut être utilisé pour forcer des conversions implicites (par exemple, des objets non const en objets const, int en double, etc.), et il peut également être utilisé pour inverser de nombreuses conversions de ce type (par exemple, un le pointeur void* est converti en pointeur typé et un pointeur de classe de base est converti en pointeur de classe dérivé), mais il ne peut pas convertir un objet const en un objet non const (seul const_cast peut le faire), qui est le plus proche de C -style Convertir.

const_cast est généralement utilisé pour forcer l'élimination de la constance des objets. C'est le seul casting de style C capable de faire cela.

reinterpret_cast est destiné aux conversions de bas niveau qui conduisent à des résultats dépendants de l'implémentation (c'est-à-dire non portables), par exemple la conversion d'un pointeur en un entier. De tels transtypages devraient être extrêmement rares en dehors du code de bas niveau.

Ce qui précède est le contenu de la conversion de type forcée de C. Pour plus de contenu connexe, veuillez faire attention au site Web PHP chinois (www.php.cn) !


Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn