2011-09-05 22 views
6

¿Es posible y por qué uno querría hacerlo?static_cast para tipos definidos por el usuario

class Foo; 
class Bar; 

...... 

Foo foo; 
Bar bar = static_cast<Bar>(foo); 

Normalmente static_cast se utiliza con tipos numéricos y los punteros, pero se puede trabajar con tipos de datos definidos por el usuario, a.k.a clases?

+0

Sí, puede funcionar, pero también debe saber cómo usarlo - Aquí hay un comienzo sobre lo que hace cada elenco en C++: http://stackoverflow.com/questions/332030/when-should-static-cast-dynamic-cast-and-reinterpret-cast-be-used – birryree

Respuesta

10
Bar bar = static_cast<Bar>(foo); 

Este molde fallará. Foo y Bar son tipos incompatibles, a menos que al menos uno de lo siguiente es cierto:

  • Foo se deriva de Bar, O
  • Bar tiene un constructor que toma Foo, O
  • Foo tiene una definida por el usuario conversión a Bar.

La pregunta más importante aquí no es si se lanzará correctamente o no. La pregunta más grande y real debería ser: ¿qué quieres obtener de ese elenco? ¿Por qué querrías hacer tal cosa en primer lugar? ¿Qué se supone que haga? Quiero decir, ¿cómo se inicializaría el objeto Bar desde el objeto Foo?

La forma más sensata para convertir un tipo a otro es una de las siguientes maneras:

De cualquier definir Foo como:

class Foo : public Bar 
{ 
    //... 
}; 

o definir Bar como:

class Bar 
{ 
    public: 
     Bar(const Foo &foo); //define this constructor in Bar! 
}; 

O proporcionar una función de conversión en Foo como:

class Foo 
{ 
    public: 
     operator Bar(); //provide a conversion function Foo to Bar! 
}; 
+1

¿O no? ¿Qué pasa si 'Foo' implementa un operador de conversión a' Bar'? –

+0

@Kerrek: actualicé mi respuesta con tales detalles. – Nawaz

+1

Que garantiza un +1 –

11

Aquí está la regla:

La expresión static_cast<T>(e) es válida si y sólo si la siguiente definición de la variable es válida

T x(e); 

donde x es una variable inventada.

Por lo tanto, en general, dos tipos no relacionados no se pueden enviar el uno al otro. Sin embargo, si un tipo se deriva del otro, o si uno define una función de conversión para el otro, o si un constructor toma un único argumento del otro tipo, en estos casos static_cast estará bien definido.

¿Alguna vez tiene sentido? Por ejemplo, si T define un constructor que toma una sola U y el constructor es explicit entonces static_cast<T>(e) donde e es de tipo U tendría perfecto sentido

+1

Tiene sentido especialmente en código genérico, por ejemplo, si T podría ser un tipo definido por el usuario pero también podría ser un tipo incorporado. Entonces, si escribió '(T (e))' en lugar de 'static_cast (e)' (paréntesis adicionales para asegurarse de que no es una definición de 'e'), entonces ese es un molde de estilo C equivalente a' ((T) e) ', y para los tipos incorporados existe el riesgo de que se convierta en un' reinterpret_cast'. –

Cuestiones relacionadas