2012-07-25 4 views
7

lo que hace este¿Debo usar realmente static_cast cada vez que quiero convertir entre tipos primitivos?

long l = 1; 
char c = static_cast<char>(l); 

float f = 1.0f; 
int i = static_cast<int>(f); 

mejor que esto

long l = 1; 
char c = (char)l; 

float f = 1.0f; 
int i = (int)f; 

cuando se lanza un tipo de datos primitivo a otro?

Tengo mucho código heredado que usa el segundo estilo para el moldeado de tipos en situaciones similares, por lo que esta también es una pregunta sobre si debería o no realizar una revisión a gran escala de ese código.

+2

Puede encontrar [la respuesta de Bjarne Stroustrup] (http://stroustrup.com/bs_faq2.html#static-cast) una buena lectura. – chris

Respuesta

21

Future-proofing.

Digamos que en un futuro hago esto:

float blah = 1.0f; 
float* f = &blah; 

Ahora, int i = static_cast<int>(f); paradas compilar, pero hace un int i = (int)f;reinterpret_cast.

static_cast<int> es esto es exactamente lo que quiero que hagas. (int) es haga lo que pueda para conseguirme una int. Con este último, el compilador hará todo lo posible para obtener un valor int, y eso rara vez (¿nunca?) Es deseable.

+0

No es realmente deseable, pero sucede. Por ejemplo, uno de los posibles retornos de [esta función] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms633585 (v = vs.85) .aspx) es un puntero a la función. El tipo de retorno de la función es 'long' o' __int64'. – chris

+0

@chris Oh, eso es raro. Pero un 'reinterpret_cast' funcionaría bien de todos modos. –

+0

De hecho. La mayor parte de la API proviene directamente de C, y usan todo tipo de "hacks" para hacer lo que necesitan. – chris

1

El problema con los modelos de estilo C es que le permiten hacer conversiones que no pretendía.

Es algo que debe hacer en el futuro pero no volvería a cambiarlo a menos que encuentre un problema.

6

Sí, deberías.

Los moldes son una fuente importante de errores. Son formas de evitar el sistema de tipos, que es uno de los mejores buscadores de errores disponibles para los programadores.

Un static_cast es mucho más visible y mucho más específico que un antiguo elenco de c-style. Quieres que se destaquen. Quieres que sean obvios cuando estás depurando. Quiere que venga el siguiente programador para comprender por qué lo está haciendo.

El hecho de que sea más difícil escribir static_cast<blah>(foo) también es una ventaja, ya que lo alentará a lanzar solo cuando sea absolutamente necesario.

8

El cada vez es un poco una indicación.

No conviene convertir entre tipos primitivos tan a menudo que escribir algunos caracteres adicionales cada vez es una tarea demasiado onerosa. Es como quejarse de que tienes que usar un casco cada vez que realizas alguna actividad peligrosa. Si le parece que usar el casco es demasiado molesto, es probable que esté involucrado en actividades peligrosas con demasiada frecuencia en lugar del requisito del casco.

En cuanto a abordar el código heredado, puede consultar this question para obtener algunas respuestas (incluida la mía).

2

Un elenco de constructor es una alternativa. Suponiendo que hay un constructor de conversión definido.Por ejemplo:

int i(0); 
float f(3.14F); 
i = int(f); 

Sin embargo, usted definitivamente debe preferir static_cast y otra C++ proyecta a través de una conversión de estilo C como las que básicamente decir "probar cada molde hasta que algo funciona", que finalmente llegará al equivalente de un reinterpret_cast y probablemente dará tu comportamiento incorrecto

+1

AFAIK 'constructor cast' es equivalente al elenco estilo c. –

+0

Quizás sea * un poco * más seguro, pero sí, se obtendría el mismo problema al introducir punteros. La solución ideal, por supuesto, es no lanzar nada y simplemente usar los tipos correctos. – AJG85

+0

Cuando digo equivalente, lo digo en serio. 5.2.3 pt 1: un simple especificador de tipo (7.1.6.2) o typename-specifier (14.6) seguido de una parenthesized expression-list construye un valor del tipo especificado dada la lista de expresiones. Si la lista de expresiones es una sola expresión, la expresión de conversión de tipos es equivalente (en definición, y si se define en el significado) a la correspondiente expresión de conversión (5.4). –

Cuestiones relacionadas