2011-12-10 13 views
8

lo tanto, tuve un examen al otro día, y una de las preguntas era algo muy parecido a esto:Sobrecarga de static_cast?

Tenemos una clase llamada Square que mantiene una variable int side. ¿Cómo podemos hacer posible que cout << static_cast<int>(aSquare) <<endl; imprima el área de aSquare?

¿Eso es posible?

Respuesta

18

Es posible hacer ese trabajo, pero no a través de la sobrecarga static_cast<>(). Lo hace por la sobrecarga del operador encasillado:

class Square 
{ 
public: 
    Square(int side) : side(side) {} 
    operator int() const { return side * side; } // overloaded typecast operator 
private: 
    int side; 
}; 

// ... 

// Compiler calls Square::operator int() to convert aSquare into an int 
cout << static_cast<int>(aSquare) <<endl; 

Tenga en cuenta que los operadores sobrecargados Typecast más a menudo que no tiende a hacer más daño que bien. Hacen posibles muchas operaciones de lanzamiento implícitas sin sentido. Cuando lees este fragmento de código a continuación, ¿crees que "a va a obtener el área de s"?

Square aSquare; 
int a = aSquare; // What the heck does this do? 

I certainly do not. Esto hace mucho más sentido y es mucho más legible:

Square aSquare; 
int a = aSquare.GetArea(); 

no hablar de que normalmente se desean poder acceder a otra información sobre Square, como GetSide() o GetApothem() o GetPerimeter() o lo que sea. operator int() obviamente puede devolver solo un int, y no puede tener múltiples operator int() s como miembros de una clase.

Aquí hay otra situación en la que hace operator int() código que compila sin embargo, no tiene ningún sentido:

Square s; 
if(s > 42) {} // Huh?! 

¿Qué significa para un Square a ser mayor que 42? No tiene sentido, pero con el operator int() el código anterior se compilará como Shape ahora es convertible a int que se puede comparar con otro int con un valor 4.

Así que no escriba a los operadores de tipografía de esa manera. De hecho, si está sobrecargando los operadores de tipografía, es posible que desee pensar dos veces acerca de lo que está haciendo. En realidad, solo hay unos pocos casos en los que la sobrecarga del operador de conversión es útil en C++ moderno (por ejemplo, the safe bool idiom).

+0

+1: una clase Square podría usar varios métodos más, p. 'int GetSideLength() const',' int GetPerimeter() const', y es para desambiguación que se debe usar un método con nombre para 'GetArea()'. – rwong

+0

Gracias por la elaborada respuesta. – Radix

+2

@In silico: con C++ 11 la expresión bool segura ya no es necesaria, ya que C++ 11 admite la palabra clave 'explicit' para los operadores de conversión. – smerlin

1

Se podría proporcionar un operador de conversión para la clase Square:

class Square 
{ 
public: 
    operator int() 
    { 
     return side * side; 
    } 
private: 
    int side; 
}; 
+0

debe devolver el área, no el lado – Dani

+2

Se mantiene verdadero para instancias muy pequeñas de cuadrado. –

+2

@ Dani: Creo que te estabas perdiendo el punto. Estoy seguro de que OP sabe cómo calcular el área. La pregunta respondió correctamente cómo obtener un int del objeto cuadrado que es la parte técnica de la pregunta. –

4

Usted puede sobrecargar el operador de conversión:

struct square { 
    operator int() const { 
    return (side * side); 
    } 
    int side; 
}; 

El único problema es que se va a utilizar de forma implícita, y echando doesn No tiene mucho sentido aquí. Tampoco se puede distinguir entre los diferentes tipos de moldes (static_cast, c-estilo, etc.)

Ésta es la mejor forma de hacer las cosas:

struct square { 
    int get_area() const { 
    return (side * side); 
    } 
    int side; 
} 

Si tiene que usar un yeso, el uso de C++ 11 característica y marque explicit. Esto evita los errores implícitos de lanzamiento.