2011-12-08 14 views
7

Ho la seguente funzione di modello utilizzata per scaricare dati di qualsiasi tipo standard in un flusso di output binario.cast di c-style vs reinterpret_cast

template<typename T> static void 
dump (const T& v, ostream& o) { 
    o.write (reinterpret_cast<const char*>(&v), sizeof(T)); 
} 

Invece del reinterpret_cast potrei anche usare uno stile di C (const char *). C'è qualche ragione particolare per usare reinterpret_cast? Ho letto alcuni altri post in cui reinterpret_cast era disapprovato. Ma l'uso di cui sopra è legale e non può essere sostituito con qualsiasi altra cosa, giusto?

Grazie

+0

Suppongo che tu conosca la conseguenza di ciò (il file risultante può essere riletto solo dal programma compilato con le stesse opzioni con lo stesso compilatore sulla stessa architettura). – curiousguy

+0

Qualcuno mi darà un pugno per averlo detto, ma se tu * vuoi * usare i cast in stile C, puoi sempre lasciare un commento generico-radicale che non puoi assolutamente perdere. C'era * un * modo * per trovare il tuo 'const's in C, anche. ¯ | _ (ツ) _ | ¯ Naturalmente dovresti badare ai pericoli, però. –

risposta

10

Il problema con C-Style getta è che fanno un sacco sotto il cofano. Vedi qui per una spiegazione dettagliata: http://anteru.net/2007/12/18/200/

Si dovrebbe cercare di utilizzare sempre i cast di C++, rendendo la vita più facile a lungo termine. Il problema principale con i cast in stile C in questo caso è che potresti aver scritto (char*)(&v) mentre con reinterpret_cast, avresti bisogno di un ulteriore const_cast, quindi è un po 'più sicuro. Inoltre puoi facilmente trovare reinterpret_cast con un'espressione regolare, che non è possibile per i cast di tipo C.

+2

Non hai nemmeno bisogno di un'espressione regolare per "reinterpret_cast", una semplice ricerca di testo (buon vecchio "Trova" nella maggior parte degli editor) è sufficiente :) –

+3

Arg, sì. Ho iniziato che non è possibile regex per un cast in stile C, e quindi la frase viene chiusa al contrario;) – Anteru

+0

Will vorrebbe trovare tutti i cast? – curiousguy

1

reinterpret_cast si disapprova quando viene utilizzato per sostituire uno static_cast o dynamic_cast. Si usa incoraggiarlo per sostituire un cast di Do.

I nuovi getti hanno vantaggi rispetto ai modelli in C. Per esempio, puoi limitare il cast che vuoi realmente, per un altro è molto più facile fare una ricerca testuale per i nuovi cast che per i cast di C.

+1

"_do una ricerca testuale per i nuovi gessi_" quanto spesso l'hai fatto? – curiousguy

+0

@curiousguy: l'ho fatto un paio di volte. Non mi importa quasi mai di aver preso qualcosa da un cast, ma spesso mi interessa che abbia fatto un particolare passo che, a quanto mi risulta, riguarda un'operazione di cast. Non sto cercando il cast, * di per sé *, sto cercando qualcos'altro che mi è capitato di sapere usato un cast. –

4

Non c'è differenza. Nella situazione data, il cast in stile C è esattamente un "reinterpret" -cast.

Il motivo per cui preferisci i cast di C++ è che sono espliciti su su ciò che stanno trasmettendo. Un cast in stile C cercherà sempre di ricorrere al cast più crudo possibile, se necessario, mentre il cast in stile C++ compila solo se è possibile come previsto: un cast statico riesce solo se i valori sono convertibili oi puntatori/riferimenti sono compatibili e una costanza funziona solo se l'origine e il target sono versioni qualificate cv l'una dell'altra. Un reinterpret-cast afferma esplicitamente che si desidera esaminare una rappresentazione binaria sottostante. (Si noti che gli unici lanci di reinterpret validi sono solitamente quelli a vuoto o puntatore char, a meno che non facciano parte di alcuni trucchetti più grandi.)

+0

"_Si noti che gli unici cast di reinterpret validi sono in genere quelli di void-() pointer_" perché vuoi trasmettere a 'void *'? – curiousguy

+0

@curiousguy: placement-new ... –

+0

Non è necessario 'reinterpret_cast' qui; 'static_cast' va bene. (Mi sarebbe piaciuto uno standard 'implicit_cast'.) – curiousguy

3

Il casting in stile C è molto molto pericoloso. Quindi C++ categoriale ha suddiviso il casting in tipi inferiori in base all'utilizzo tipico,

dynamic_cast (espressione): consente di eseguire il cast tra classi gerarchiche appropriate.

const_cast (espressione): allontana la costante.

static_cast (espressione) - In una certa misura in stile C, ma rispetta ancora alcune incompatibilità tra i tipi e non consente.

reinterpret_cast (espressione) - Se il requisito non viene soddisfatto, questo è disponibile. Casting in stile C ma con un nome. Quindi sarà facile trovarlo in una grande base di codice.

Nota: la maggior parte di "reinterpret_cast" può essere eliminata con una progettazione corretta. In altre parole "reinterpret_cast" è necessario significa, molto probabilmente qualcosa non va nel design.

Aggiornamento: Questa dovrebbe essere l'ultima opzione e, nel caso precedente, l'utilizzo è corretto. Ora menzionare reinterpret_cast darà al lettore l'impressione che intenzionalmente lo scrittore abbia scelto di non preoccuparsi della sicurezza del tipo. Ma l'uso di casting in stile c non darà quell'impressione.

+0

Ma immagino che reinterpret_cast usato nel codice sopra sia molto semplice - e non si adatti alla tua riprogettazione? – shekhar

+0

Come ho già detto, questa dovrebbe essere l'ultima opzione e, nel caso precedente, l'utilizzo è corretto. Ora menzionare reinterpret_cast darà al lettore l'impressione che intenzionalmente lo scrittore abbia scelto di non preoccuparsi della sicurezza del tipo. Ma l'uso di casting in stile c non darà quell'impressione. – rakesh

Problemi correlati