2011-09-05 12 views
6

È possibile e perché si vorrebbe farlo?statico_cast per i tipi definiti dall'utente

class Foo; 
class Bar; 

...... 

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

Normalmente static_cast viene utilizzato con tipi numerici e puntatori, ma può funzionare con tipi di dati definiti dall'utente, a.k.a classi?

+0

Sì, può funzionare, ma devi anche sapere come usarlo - Ecco un inizio su cosa fa ogni cast in C++: http://stackoverflow.com/questions/332030/when-should-static-cast-dynamic-cast-and-reinterpret-cast-be-used – birryree

risposta

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

Questo cast fallirà. Foo e Bar sono tipi non compatibili, a meno che, almeno una delle seguenti condizioni:

  • Foo è derivato da Bar, O
  • Bar ha un costruttore che accetta Foo, O
  • Foo ha una definita dall'utente conversione in Bar.

La domanda più grande qui non è se verrà lanciato correttamente o meno. La domanda più grande e reale dovrebbe essere: cosa vuoi ottenere da questo cast? Perché vorresti fare una cosa del genere in primo luogo? Cosa dovrebbe fare? Voglio dire, come sarebbe l'oggetto Bar inizializzato dall'oggetto Foo?

Il modo ragionevole per convertire un tipo ad un altro è uno dei seguenti modi:

Sia definire Foo come:

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

Oppure stabilire Bar come:

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

O fornire una funzione di conversione in Foo come:

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

Oppure fallirà? Cosa succede se 'Foo' implementa un operatore di conversione in' Bar'? –

+0

@Kerrek: ho aggiornato la mia risposta con tali dettagli. – Nawaz

+1

Che garantisce un +1 –

11

Ecco la regola:

L'espressione static_cast<T>(e) è valida se e solo se la seguente definizione variabile è valida

T x(e); 

dove x è qualche variabile inventata.

Quindi, in generale, due tipi non correlati non possono essere trasmessi l'uno all'altro. Tuttavia, se un tipo è derivato dall'altro, o quando uno definisce una funzione di conversione all'altro o ha un costruttore che prende un singolo argomento dell'altro tipo, in questi casi static_cast sarà ben definito.

Ha mai senso? Ad esempio, se T definisce un costruttore che accetta una singola U e il costruttore è explicit allora static_cast<T>(e) dove e è di tipo U sarebbe perfettamente sensato

+1

Ha senso soprattutto nel codice generico, ad esempio se T potrebbe essere un tipo definito dall'utente ma potrebbe anche essere un tipo predefinito. Quindi se hai scritto '(T (e))' invece di 'static_cast (e)' (extra parens per assicurarti che non sia una definizione di 'e'), allora questo è un cast in stile C equivalente a' ((T) e) ', e per i tipi built-in c'è il rischio che si trasformi in un' reinterpret_cast'. –

Problemi correlati