Hai etichettato questo con tre lingue e le risposte sono davvero molto diverse tra le tre. La discussione del C ++ implica più o meno la discussione anche dei cast in C, e questo fornisce (più o meno) una quarta risposta.
Dato che è quello che non hai menzionato esplicitamente, inizierò con C. I cast hanno una serie di problemi. Uno è che possono fare una serie di cose diverse. In alcuni casi, il cast non fa altro che dire al compilatore (in sostanza): "taci, so cosa sto facendo" - cioè, assicura che anche quando fai una conversione che potrebbe causare problemi, il compilatore non ti avviserà di questi potenziali problemi. Solo per esempio char a=(char)123456;,. Il risultato esatto di questa implementazione definita (dipende dalla dimensione e dalla firma dichar), e tranne in situazioni piuttosto strane, probabilmente non è utile. I cast C variano anche a seconda che siano qualcosa che accade solo in fase di compilazione (cioè, stai solo dicendo al compilatore come interpretare / trattare alcuni dati) o qualcosa che accade in fase di esecuzione (ad esempio, una conversione effettiva da double a lungo).
Il C ++ tenta di risolvere questo problema almeno in una certa misura aggiungendo un numero di "nuovi" operatori di cast, ognuno dei quali è limitato solo a un sottoinsieme delle capacità di un cast in C. Ciò rende più difficile (ad esempio) eseguire accidentalmente una conversione che non intendevi davvero: se intendi solo eliminare la costanza su un oggetto, puoi usarlo const_casted essere sicuro che l' unica cosa che può influenzare è se un oggetto è const, volatileo non. Al contrario, a static_castnon è consentito influenzare se un oggetto è constovolatile. In breve, hai la maggior parte degli stessi tipi di funzionalità, ma sono classificati in modo che un cast possa generalmente eseguire solo un tipo di conversione, in cui un singolo cast in stile C può eseguire due o tre conversioni in un'unica operazione. L'eccezione principale è che puoi usare un dynamic_castal posto di static_casta almeno in alcuni casi e nonostante sia scritto come a dynamic_cast, finirà davvero come a static_cast. Ad esempio, puoi utilizzare dynamic_castper spostarti verso l'alto o verso il basso una gerarchia di classi, ma un cast "alto" della gerarchia è sempre sicuro, quindi può essere fatto staticamente, mentre un cast "basso" della gerarchia non è necessariamente sicuro, quindi è fatto dinamicamente.
Java e C # sono molto più simili tra loro. In particolare, con entrambi il casting è (praticamente?) Sempre un'operazione di runtime. In termini di operatori di cast C ++, di solito è il più vicino a un dynamic_castin termini di ciò che è realmente fatto - cioè, quando si tenta di eseguire il cast di un oggetto su un tipo di destinazione, il compilatore inserisce un controllo in fase di esecuzione per vedere se tale conversione è consentita e genera un'eccezione se non lo è. I dettagli esatti (ad esempio, il nome usato per l'eccezione "cast errato") variano, ma il principio di base rimane per lo più simile (sebbene, se la memoria serve, Java rende i cast applicati ai pochi tipi non oggetto come intmolto più vicini a C cast - ma questi tipi sono usati abbastanza raramente che 1) non me lo ricordo per certo, e 2) anche se è vero, non importa molto comunque).
Guardando le cose più in generale, la situazione è piuttosto semplice (almeno IMO): un cast (ovviamente abbastanza) significa che stai convertendo qualcosa da un tipo a un altro. Quando / se lo fai, solleva la domanda "Perché?" Se vuoi davvero che qualcosa sia di un tipo particolare, perché non l'hai definito come quel tipo con cui iniziare? Questo non vuol dire che non ci sia mai un motivo per eseguire una tale conversione, ma ogni volta che accade, dovrebbe sorgere la domanda se è possibile riprogettare il codice in modo da utilizzare il tipo corretto dappertutto. Anche conversioni apparentemente innocue (ad esempio, tra numero intero e virgola mobile) dovrebbero essere esaminate molto più da vicino di quanto sia comune. Nonostante il loro aspettosomiglianza, i numeri interi dovrebbero davvero essere usati per tipi di cose "contate" e virgola mobile per tipi di cose "misurate". Ignorare la distinzione è ciò che porta ad alcune affermazioni folli come "la famiglia americana media ha 1,8 figli". Anche se tutti possiamo vedere come ciò avvenga, il fatto è che nessuna famiglia ha 1,8 figli. Potrebbero averne 1 o 2 o potrebbero averne di più, ma mai 1.8.