2012-01-31 7 views
14

estoy leyendo efectiva C++ y me encontré con este ejemplo:¿Por qué static_cast (* this) a una clase base crea una copia temporal?

class Window {        // base class 
public: 
    virtual void onResize() { ... }    // base onResize impl 
    ... 
}; 

class SpecialWindow: public Window {   // derived class 
public: 
    virtual void onResize() {     // derived onResize impl; 
    static_cast<Window>(*this).onResize(); // cast *this to Window, 
               // then call its onResize; 
               // this doesn't work! 

    ...          // do SpecialWindow- 
    }           // specific stuff 

    ... 

}; 

El libro dice:

Lo que no puede esperar es que no invoca esa función en el objeto actual ! En cambio, el elenco crea una copia nueva y temporal de la parte de la clase base de * this, luego invoca onResize en la copia.

¿Por qué static_cast (código anterior) crea una nueva copia? ¿Por qué no simplemente usar la parte de la clase base del objeto?

+0

Si fue lanzado a 'static_cast (* this) .onResize();', entonces creo que usaría el objeto actual. (Tenga en cuenta el 'y'). Aunque no estoy seguro –

+0

static_cast (esto) -> onResize(); también debería funcionar, pero por supuesto Window :: onResize(); es el correcto aquí. – Trass3r

Respuesta

25

Porque este código pregunta para crear un objeto nuevo. Este código quiere hacer un objeto Window desde *this - que se puede hacer usando el copia constructor de Window.

Lo que se quiere en cambio, es la siguiente:

static_cast<Window&>(*this).onResize(); 
//    ^
//    note the & 

Esto significa que quiero hacer una Window& de *this - que es un conversión implícita de una clase derivada referencia (*this es un SpecialWindow&) a una referencia Window&.

Sin embargo, es mejor simplemente llamada de la versión específica de la función miembroonResize() al que desea llamar:

Window::onResize(); // equivalent to this->Window::onResize(); 
2

Debido a que está lanzando objeto real no es un puntero o referencia. Es exactamente la misma forma de fundir double a int crea una nueva int - sin reutilizar la parte de double.

6

Esto se debe a que el código está emitiendo un valor Window en lugar de una referencia Window&. Según la norma, esta forma de la colada es equivalente a llamar (C++ 11 §5.2.9/4 = C++ 03 §5.2.9/2)

Window __t (*this); 
__t.onResize(); 

que invoca el constructor de copia de Window, y realiza onResize en esa copia.

(La forma correcta de llamar a un método de la superclase es

Window::onResize(); 

)

1

Contraste:

static_cast<Window>(*this) 

con:

static_cast<Window&>(*this) 

Uno llama a la copia constructor, el otro d oes no. ¿Eso ayuda?

Cuestiones relacionadas