it-swarm.it

cast di stile c o cast di stile c ++

Allora, cosa usi?

int anInt = (int)aFloat;

o

int anInt = static_cast<int>(aFloat);
// and its brethren

E, soprattutto, perché?

21
bastibe

Innanzitutto, capisci che quelle righe non sono equivalenti .

int* anInt = (int*)aFloat; // is equivalent to

int* anInt = reinterpret_cast<int*>(aFloat); 

Quello che sta succedendo qui è che il programmatore sta chiedendo al compilatore di fare tutto il possibile per realizzare il cast.

La differenza è importante perché l'uso di static_cast richiederà solo un tipo di base "sicuro" in cui convertire, dove reinterpret_cast verrà convertito in qualsiasi cosa, possibilmente mappando il layout di memoria desiderato sulla memoria dell'oggetto specificato.

Pertanto, poiché il "filtro" non è lo stesso, l'utilizzo di cast specifici è più chiaro e sicuro rispetto all'utilizzo del cast C, se si fa affidamento sul compilatore (o impl runtime se si utilizza dynamic_cast) per dirti dove hai fatto qualcosa di sbagliato , evitando C cast e reinterepret_cast.

Ora che questo è più chiaro, c'è un'altra cosa: static_cast, reinterpret_cast, const_cast e dynamic_cast sono più facili da cercare .

E l'ultimo punto: sono brutti . Questo è voluto. Il codice potenzialmente difettoso, gli odori di codice, gli ovvi "trucchi" che potrebbero generare bug, sono più facili da rintracciare quando sono associati a un brutto aspetto. Il codice errato dovrebbe essere brutto .

Questo è "in base alla progettazione". E ciò consente allo sviluppatore di sapere dove avrebbe potuto fare meglio le cose (evitando totalmente i cast, se non proprio necessari) e dove va bene ma è "documentato" nel codice "contrassegnandolo" come brutto.

Un motivo secondario per introdurre il cast di nuovo stile era che i cast in stile C sono molto difficili da individuare in un programma. Ad esempio, non è possibile cercare comodamente i cast utilizzando un normale editor o elaboratore di testi. Questa quasi invisibilità dei cast in stile C è particolarmente sfortunata perché sono potenzialmente dannosi. Un'operazione brutta dovrebbe avere una brutta forma sintattica. Quell'osservazione faceva parte della ragione per scegliere la sintassi per i cast di nuovo stile. Un ulteriore motivo era che i cast di nuovo stile corrispondessero alla notazione del modello, in modo che i programmatori potessero scrivere i propri cast, in particolare i cast controllati in fase di esecuzione.

Forse, poiché static_cast è così brutto e relativamente difficile da digitare, è più probabile che tu ci pensi due volte prima di usarne uno? Sarebbe positivo, perché i cast sono per lo più evitabili nel C++ moderno.

Fonte: Bjarne Stroustrup (creatore di C++)

47
Klaim

I cast C++ sono più restrittivi (quindi esprimi meglio le tue intenzioni e rendi più facile la revisione del codice, ecc.). Sono anche molto più facili da cercare, se mai ne hai bisogno.

37
Bruce Stephens

Opzione C: un cast di tipo "C++", perché non è distinguibile da una costruzione:

int anInt = int(aFloat);

o anche:

int anInt(aFloat);

A parte questo, a parte questi banali casi con primitivi, che sono ben compresi, preferisco usare x_cast <> s su cast in stile C. Ci sono tre ragioni per cui:

  • Definiscono più strettamente l'operazione che il programmatore stava cercando di eseguire.

  • Possono eseguire azioni che non possono essere lanciate in stile C (specialmente nel caso di dynamic_cast <>, che può eseguire il cast incrociato tra i rami di una catena a ereditarietà multipla).

  • Sono brutti. Dichiarano a gran voce che il programmatore sta lavorando contro il sistema di tipi. In questo caso, è una cosa buona .

13
Kaz Dragon

Ho alcune regole sui cast in stile C/C++:

  1. Disapplicare una const deve sempre usare un const_cast. Per ovvie ragioni. Sfortunatamente, la mia regola di non applicare una const che fa alzare la tastiera e rompere il dito del programmatore non è stata approvata.
  2. Qualsiasi shenanigan in stile manipolazione dei bit a cui i programmatori si avvicinano quando si avvicinano al metal dovrebbe usare reinterpret_cast. È davvero il tipo di cast che C non ha: fingi che i bit di questo numero intero siano in realtà bit di un float. Questo evita spiacevoli come (int)(*(int*)(&floatVar)).
  3. Se digiti le parole "dynamic_cast ", interrompi e rivaluta la gerarchia e il design della tua classe polimorfica. Continua a rivalutare il design della gerarchia di classi fino a quando non puoi eliminare quelle parole.
  4. Non preoccuparti di static_cast.

Il ragionamento dietro # 4 è semplicemente che non importa. Le circostanze che non rientrano nelle altre regole sono ovvie o veramente di basso livello. Una conversione ben comprensibile di tipi semplici come int-to-float non dovrebbe richiedere una sintassi speciale. E se sei nel profondo, brutto fegato di qualcosa, beh, sei nel profondo, brutto fegato di qualcosa. Non c'è bisogno di attirare l'attenzione sul fatto che "qui ci sono draghi", poiché i denti, gli artigli e il fuoco l'hanno praticamente già ceduto.

7
Nicol Bolas

Se scrivi il codice in C usa un cast C. Se scrivi in ​​C++ usa un cast C++.

Mentre la maggior parte dei casting rompe la corretta sicurezza del tipo, quelli in C++ sono più restrittivi, e quindi sei leggermente meno insicuro rispetto al tipo di un cast in C.

Posso tollerare qualcuno usando (T *) NULL anche se per forzare un sovraccarico ...

7
CashCow

Come notato dai post precedenti, il cast C++ (statico) è in pratica un po 'più sicuro.

Potrebbe essere intelligente cercare qualche informazione in più sui diversi tipi di casting e sui loro pro e contro.

Giusto per avere più informazioni sul perché. .

http://en.wikipedia.org/wiki/Static_cast

http://en.wikipedia.org/wiki/Dynamic_cast

http://en.wikipedia.org/wiki/Reinterpret_cast

4
the JinX

Dipende molto dalla lingua con cui sto lavorando, dato che sai cosa dicono: a Roma parla il romano. Quindi, se sto programmando in C, provo ad usare le funzionalità C al massimo, ma se sto programmando in C++ vado avanti e utilizzo le funzionalità C++ al massimo, anche se alcune persone non amano questo approccio perché dicono che rende il codice "meno portatile", dico che non mi interessa, sono in C++ e programmazione in C++, e ho bisogno di un compilatore completamente compatibile C++ per compilare il codice, altrimenti lavorerei con qualcosa di diverso innanzitutto.

3
Coyote21

static_cast etc sono stati inventati a causa di problemi con i cast in stile C quando usati nei template. Se stai scrivendo un modello, o se il tuo codice può essere successivamente convertito in modello, è una buona idea usare cast in stile C++. Il motivo è perché i cast in stile C++ esprimono meglio l'intento, quindi daranno i risultati previsti nei casi in cui i cast in stile C faranno la cosa sbagliata (dati i tipi particolari come parametri del modello).

A parte questo, dico di usare i cast in stile C++ se hai un problema specifico che ne ha bisogno: dynamic_cast è il più comune, ma probabilmente non è una cosa di tutti i giorni.

Qualsiasi altra cosa, e un cast in stile C potrebbe essere un po 'meno disordinato e aiutare la leggibilità, o forse non dipende da quanto il lettore abbia familiarità con quello stile di cast in questi giorni. A mio avviso non è molto importante, soprattutto una preferenza personale, anche se non sorprenderti se alcune persone non apprezzano lo stile C.

Nota finale: se hai bisogno di così tanti cast che questo è un grosso problema, probabilmente stai facendo qualcos'altro di sbagliato. Ci sono eccezioni a ciò in alcuni casi, ma la maggior parte del codice di alto livello non dovrebbe richiedere molti cast (se presenti).

3
Steve314