2010-12-02 10 views
11

Qu'est-ce que Type de conversion et quelle est Type de coulée?Type Conversion/Coulée Confusion en C++

Quand dois-je utiliser chacun d'entre eux?

Détail: Désolé si c'est une question évidente; Je suis nouveau en C++, venant d'un arrière-plan de rubis et étant utilisé pour to_s et to_i et similaires.

Répondre

15

Conversion est quand une valeur est , um, converti en un type différent. Le résultat est une valeur du type cible, et il y a des règles pour quelle valeur de sortie résulte de quelle entrée (du type source).

Par exemple:

int i = 3; 
unsigned int j; 
j = i; // the value of "i" is converted to "unsigned int". 

Le résultat est la valeur unsigned int qui est égale à i modulo UINT_MAX+1, et cette règle fait partie de la langue. Donc, dans ce cas, la valeur (en anglais) est toujours "3", mais c'est une valeur int non signée de 3, qui est subtilement différente d'une valeur int signée de 3.

Notez que la conversion est automatique. utilisé une valeur int signée dans une position où une valeur int non signée est requise, et la langue définit ce que cela signifie sans que nous disions réellement que nous sommes en train de convertir. C'est ce qu'on appelle une "conversion implicite".

"Coulée" est une conversion explicite.

Par exemple:

unsigned int k = (unsigned int)i; 
long l = long(i); 
unsigned int m = static_cast<unsigned int>(i); 

sont tous les moulages. Spécifiquement, selon 5.4/2 de la norme, k utilise une cast-expression, et selon 5.2.3/1, l utilise une chose équivalente (sauf que j'ai utilisé un type différent). m utilise un "opérateur de conversion de type" (static_cast), mais d'autres parties de la norme se réfèrent également à celles-ci en tant que "moulages".

types définis par l'utilisateur peuvent définir des "fonctions de conversion" qui fournissent des règles spécifiques pour convertir votre type à un autre type, et les constructeurs mono-arg sont utilisés dans les conversions aussi:

struct Foo { 
    int a; 
    Foo(int b) : a(b) {}     // single-arg constructor 
    Foo(int b, int c) : a(b+c) {}   // two-arg constructor 
    operator float() { return float(a); } // conversion function 
}; 

Foo f(3,4);    // two-arg constructor 
f = static_cast<Foo>(4); // conversion: single-arg constructor is called 
float g = f;    // conversion: conversion function is called 
3

La fusion classique (quelque chose comme (Bar)foo en C, utilisé en C++ avec reinterpret_cast<>) est lorsque le contenu réel de la mémoire d'une variable est supposé être une variable d'un type différent. La conversion de type (c'est-à-dire lexical_cast<> de Boost ou d'autres fonctions définies par l'utilisateur qui convertissent les types) est quand convertit une une variable d'un type à l'autre, comme un entier à une chaîne, où du code s'exécute pour former logiquement un chaîne sur un entier donné.

Il est également coulée statique et dynamique, qui sont utilisés dans l'héritage, par exemple, pour forcer l'utilisation des fonctions membres d'un parent sur le type d'un enfant (dynamic_cast<>), ou vice-versa (static_cast<>). coulée statique vous permet également d'effectuer la typique conversion de type « implicite » qui se produit lorsque vous faites quelque chose comme:

 
float f = 3.14; 
int i = f; //float converted to int by dropping the fraction 

qui peut être réécrite comme:

 
float f = 3.14; 
int i = static_cast<int>(f); //same thing 
+2

+1, mais il convient de noter que cette terminologie n'est pas strictement respectée. Considérez 'int i; float f = static_cast (i) '- par votre logique (et je suis d'accord), c'est une * conversion *, pas une distribution. C++ utilise toujours 'static_cast' (et oui, je suis conscient qu'une conversion implicite fonctionnerait ici). En d'autres termes: vous avez donné la distinction sémantiquement la plus significative des deux termes. Mais C++ ne suit pas cette distinction. –

+1

Edité pour clarifier certaines choses, j'espère que je ne répandrai pas de désinformation. –

+1

Vous semblez dire qu'une * expression-cast * (5.4/2) n'est pas un cast, mais plutôt une conversion. Cela peut être une définition utile de "cast" contre "conversion" pour les langages de programmation en général, mais ce n'est pas la définition de "cast" utilisée dans la norme C++. –

2

En C++, toute expression a un type. lorsque vous utilisez une expression d'un type (disons de type S) dans un contexte où une valeur d'un autre type est requise (disons le type D), le compilateur essaie de convertir l'expression de type S en type D. Si une telle conversion implicite ne n'existe pas, cela entraîne une erreur. Le type de cast cast n'est pas standard mais est identique à la conversion.

E.G.

void f(int x){} 

char c; 

f(c); //c is converted from char to int. 

Les conversions sont classés et vous pouvez google pour promotions vs. conversions pour plus de détails.

Il y a 5 opérateurs de la distribution explicites en C++ static_cast, const_cast, reinterpret_cast et dynamic_cast, ainsi que la C-style cast

+0

Wow, merci les gars, je ne m'attendais pas à d'aussi bonnes réponses si rapidement, merci! – Ell

+2

@Ell: tag C++ est occupé :) –

2

conversion de type lorsque vous convertissez en fait un type dans un autre type, par exemple une chaîne en un entier et vice -versa, un cast de type est quand le contenu réel de la mémoire n'est pas changé, mais le compilateur l'interprète d'une manière différente.

0

Le moulage de type indique que vous traitez un bloc de mémoire différemment.

int i = 10; 
int* ip = &i; 
char* cp = reinterpret_cast<char*>(ip); 
if (*cp == 10) // Here, you are treating memory that was declared 
{     // as int to be char. 
} 

La conversion de type indique que vous convertissez une valeur d'un type à un autre.

char c = 'A'; 
int i = c; // This coverts a char to an int. 
      // Memory used for c is independent of memory 
      // used for i.