2 votes

Conversion de type et transtypage des pointeurs en C++

J'ai essayé de comprendre les différences entre la conversion de type et le cast de type. Ce que j'ai appris, c'est qu'essentiellement lorsque la valeur sous-jacente ou la représentation binaire d'un type est changée en une autre valeur, nous avons effectué une conversion. Alors que dans un cast de type pur, nous disons simplement au compilateur de traiter le motif binaire comme un autre type. J'ai utilisé 'pur' car un cast peut entraîner une conversion, auquel cas on l'appelle une 'conversion explicite'.

J'ai pensé à deux exemples pour illustrer cette différence. Premier:

float x = 1.5;
float* p1 = &x;
int* p2 = (int*) p1;
int i = *p2;

Ici, caster un type de pointeur n'effectue aucune opération sur la valeur du pointeur. Donc c'est un cast pur. Dans ce cas, cela a entraîné un comportement indéfini car nous obtenons la valeur int en fonction de la représentation binaire de 1,5, 1069547520 pour être précis.

Deuxième:

B* b = new D();
D* d = static_cast(b);

Où D est dérivé de B. Ici, une conversion implicite est faite dans la première ligne. Dans la deuxième ligne également, le cast est en fait une conversion. Ce sont des conversions car la valeur du pointeur peut être modifiée, ajustant la valeur si nécessaire pour pointer vers l'objet D complet ou le sous-objet B (je n'ai pas complètement compris comment les offsets fonctionnent cependant).

Suis-je correct en appelant les casts de pointeur de classes définies par l'utilisateur des conversions ? Si c'est le cas, alors static_cast ci-dessus a également effectué une conversion (explicitement) tandis que cette réponse que j'ai lue appelle les casts un concept totalement différent:

https://stackoverflow.com/a/34268988/1219638 -

Les conversions standard sont des conversions implicites avec des significations intégrées et sont des concepts distincts des choses comme static_cast ou des casts de style C.

Aussi, pourquoi une conversion d'un pointeur de classe définie par l'utilisateur est-elle appelée une conversion standard ?

Puis-je poser une dernière question ? J'ai appris qu'un cast de style C agira comme un static_cast lorsque les types sont liés. Cela signifie-t-il qu'un cast de style C calculera également les offsets s'il le faut ?

5voto

Nicol Bolas Points 133791

Il est important de comprendre que, en ce qui concerne le langage C++, la distinction dont vous parlez n'existe pas. Tous les "*_cast" (et leurs équivalents en C) sont simplement des conversions (explicites). Et pour le langage, toutes les conversions créent un nouvel objet (ou une nouvelle référence à un objet existant si la conversion est vers un type de référence).

Les pointeurs sont des objets. int* p2 = (int*) p1; effectue une reinterpret_cast, qui crée un nouvel objet pointeur d'un type différent. p2 est un objet distinct de p1, même s'ils pointent vers la même mémoire. Si vous faites ++p2, cela n'affectera en rien sur quoi p1 pointe.

Donc, du point de vue du langage, un cast est simplement certaines conversions explicites qui utilisent une syntaxe ayant le mot "cast" dedans (ou une syntaxe équivalente à une syntaxe avec le mot "cast").

La distinction que vous essayez de faire est essentiellement quand une conversion renvoie une valeur qui est binaire identique à l'objet d'origine et quand ce n'est pas le cas. Eh bien, C++ ne s'en soucie pas vraiment ; toutes les conversions (non références) renvoient un nouvel objet. C++ n'a ni n'a besoin de terminologie pour décrire les conversions lorsque le nouvel objet est binaire identique à l'ancien. Et il y a beaucoup d'opérations "*_cast" qui peuvent ne pas renvoyer de valeurs binaires identiques, donc même si l'on désirait créer un tel concept, l'appeler un "cast" serait source de confusion.

Aussi, pourquoi une conversion d'un pointeur de classe définie par l'utilisateur est-elle appelée une conversion standard ?

Parce que c'est ainsi que les standards du C++ les appellent. Je ne veux pas dire que nous les appelons "standard" parce qu'ils sont dans le standard du C++. Je veux dire que le standard du C++ a un concept appelé "conversion standard", et les conversions entre certains types de pointeurs de classes en font partie.

Une "conversion standard" est une conversion qui peut se produire implicitement (c'est-à-dire sans syntaxe spécialisée au site de la conversion). Un pointeur vers une classe dérivée peut être converti implicitement en un pointeur vers une classe de base accessible. C'est en partie ce pour quoi sert l'héritage polymorphique : la capacité pour un code d'agir sur une instance de classe dérivée sans savoir exactement sur quel type il agit. La classe de base polymorphique fournit une interface générale que le code est écrit pour utiliser, et les classes dérivées fournissent diverses implémentations de cette interface.

2voto

user2079303 Points 4916

J'ai essayé de comprendre les différences entre la conversion de type et le transtypage.

Voici la différence :

  • Le transtypage est une expression. Il provoque une conversion de type explicitement.
  • Les conversions incluent à la fois les conversions explicites et implicites.
  • Les conversions implicites ne sont pas causées par des transtypages. Elles se produisent dans les expressions... implicitement.

Dans ce cas, cela a abouti à un comportement indéfini

Exact.

car nous obtenons la valeur int basée sur la représentation binaire de f1.5, soit 1069547520 pour être précis.

Notez que puisque le comportement est indéfini, nous ne sommes pas garantis d'obtenir cette valeur précise. Le comportement du programme pourrait être n'importe quoi ; il pourrait planter, échouer à compiler, fonctionner exactement comme vous le souhaitez, ou même fonctionner exactement de la manière dont vous ne le souhaitez pas.

Suis-je correct en appelant les transtypages de pointeurs de classes définies par l'utilisateur des conversions?

Il est courant d'appeler les transtypages des conversions. Bien que techniquement, il serait plus précis de dire que les transtypages provoquent des conversions.

Si c'est le cas, alors static_cast ci-dessus a également effectué une conversion (explicitement)

Exact.

Pourquoi une conversion du pointeur de classe définie par l'utilisateur est-elle appelée une conversion standard?

Parce que c'est un pointeur, et les conversions entre pointeurs sont des conversions standard.

Cela signifie-t-il qu'un transtypage de style C calculera également des décalages s'il le doit?

Oui. Si un static_cast doit calculer un décalage, et qu'un transtypage de style C fait un static_cast, alors le transtypage de style C calculera un décalage.

P.S. Ne pas utiliser de transtypages de style C.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X