2012-01-31 10 views
14

Sto leggendo Effective C++ e sono imbattuto in questo esempio:Perché static_cast (* this) in una classe base crea una copia temporanea?

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 

    ... 

}; 

Il libro dice:

Quello che forse non si aspettano è che non richiama quella funzione sull'oggetto corrente ! Invece, il cast crea una nuova copia temporanea della parte della classe base di * this, quindi invoca onResize sulla copia!

Perché static_cast (codice precedente) crea una nuova copia? Perché non usare solo la parte della classe base dell'oggetto?

+0

Se è stato lanciato su 'static_cast (* this). OnResize();', quindi penso che utilizzerebbe l'oggetto corrente. (Nota: '&'). Non sono sicuro però. –

+0

static_cast (this) -> onResize(); dovrebbe funzionare ma ovviamente Window :: onResize(); è quello corretto qui. – Trass3r

risposta

25

Poiché questo codice richiede per creare un nuovo oggetto. Questo codice vuole rendere un oggetto Window da *this - che può essere fatto utilizzando il copy constructor di Window.

Che cosa si vuole invece è questo:

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

Questo vuol dire voglio fare un Window& da *this - che è un implicita conversione da una classe derivata riferimento (*this è un SpecialWindow&) a un riferimento Window&.

Tuttavia, è meglio solo chiamata la versione specifica della funzione di membroonResize() che si desidera chiamare:

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

Perché si sta casting oggetto reale non un puntatore o riferimento. È ugualmente che la trasmissione di double a int crea nuovo int - non riusare la parte di double.

6

Questo perché il codice sta trasmettendo il valore a Window anziché a un riferimento Window&. Secondo lo standard, questa forma di colata è equivalente alla chiamata (C++ 11 §5.2.9/4 = C++ 03 §5.2.9/2)

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

che invoca il costruttore di copia di Window ed esegue onResize su quella copia.

(Il modo corretto di chiamare un metodo della superclasse è

Window::onResize(); 

)

1

Contrasto:

static_cast<Window>(*this) 

con:

static_cast<Window&>(*this) 

Uno chiama la copia costruttore, l'altro d o non Questo aiuta?

Problemi correlati