2014-12-17 5 views
31

Sono ben consapevole del vantaggio nell'uso di static_cast anziché della trasmissione in stile C per i tipi di puntatori.C'è qualche vantaggio nell'uso di statico_cast piuttosto che di casting in stile C per i tipi non puntatori?

Se i tipi di puntatore sono incompatibili, quindi:

  • static_cast darà un errore di compilazione in una riga specifica all'interno del codice sorgente
  • C-style fusione potrebbe portare a un errore di runtime in un punto "casuale" nell'esecuzione del programma

Ma non riesco a trovare esempi simili per i tipi senza puntatore.

In altre parole, entrambi i metodi di fusione producono lo stesso risultato per i tipi senza puntatore.

È corretto o mi sono perso qualcosa?

In caso affermativo, è static_cast utilizzato solo per i tipi non puntatori al fine di mantenere la coerenza di codifica?

+5

A un cast di tipo C non interessa se l'input o l'output sono un puntatore. Sarà felicemente convertire tra puntatori e non puntatori. –

+0

Ho trovato una bella spiegazione [qui] (http://en.cppreference.com/w/cpp/language/explicit_cast). – TobiMcNamobi

+2

@ Dinal24: Non fa riferimento alla mia domanda specifica riguardante i vantaggi di 'static_cast' rispetto al cast regolare nel caso di ** tipi non-pointer **. –

risposta

33

Un vantaggio che le altre due risposte non hanno ancora menzionato è che lo static_cast è molto più facile da individuare. Il significato delle parentesi è notoriamente sovraccarico in C++ e può essere difficile individuare i cast malvagi (o anche scorretti). Quando vedo qualcosa che termina in _cast, è come un colpo di velocità mentale: rallento e controllo attentamente perché il sistema di tipi viene sovvertito.

+11

Leggibilità ... a volte molto più importante delle ragioni tecniche. –

+4

La leggibilità e la facilità di individuazione sono buoni, ma il vero grande vantaggio di static_cast rispetto al cast di stile c mostra CTRL + F. Hai mai provato a trovare tutti i cast esistenti in stile c in una parte importante della tua base di codice? – Kaiserludi

+0

@Kaiserludi Suppongo che la 'leggibilità per strumenti' possa anche essere considerata 'leggibilità'. –

15

Suppongo che gli usi banali dei riferimenti per evitare i puntatori non contino.

In tal caso: un cast C-style può essere:

  • un const_cast
  • un static_cast
  • un static_cast seguito da un const_cast,
  • un reinterpret_cast
  • un reinterpret_cast seguito di un const_cast

con l'eccezione che le restrizioni di static_cast sulle classi di base inaccessibili vengono eliminate.

const_cast si applica solo a puntatori e riferimenti.

reinterpret_cast si applica solo a puntatori e riferimenti. Include conversioni da puntatore a intero e viceversa, ma ciò implica ancora un tipo di puntatore.

Questa eccezione speciale per static_cast si applica solo a puntatori e riferimenti.

Quindi sì, escludendo puntatori e riferimenti, hai escluso tutto ciò che il supporto di stile C supporta su un static_cast.

In caso affermativo, è static_cast utilizzato solo per i tipi senza puntatori per mantenere la coerenza di codifica?

Facciamo un'analogia: non userei una motosega per aprire un sacchetto di patatine. Potrei, ma le motoseghe sono pericolose, quindi usandone una, introdurrei rischi inutili. È molto facile usare una motosega sbagliata, e se la uso male, non esiste un meccanismo di sicurezza per prevenire incidenti.

+2

Una versione più vivida della tua analogia: puoi certamente tagliare le unghie dei piedi con una motosega, ma è meglio sapere cosa stai facendo. –

+1

@FrerichRaabe D'altra parte, se sai cosa stai facendo, non taglierai le unghie dei piedi con una motosega. :) – hvd

+3

La metafora corretta è che dovresti essere dannatamente sicuro che è un sacco di patatine che si apre con il lanciafiamme invece di un coltello, e non un sacco di popcorn o dinamite che esploderebbero in faccia, a vari livelli. –

15

È static_cast utilizzato per tipi non puntatori solo per mantenere la coerenza di codifica?

Non solo, ma anche per aiutare a mantenere la correttezza e la compatibilità futura.

Aiuta a mantenere la correttezza, dal momento che static_cast non può fare alcuni cast che un cast in stile C. può fare. Questo aiuta se commetti un errore su alcuni dei tipi coinvolti, magari gestendo un puntatore mentre sei convinto che sia un numero intero (e in basso diversi livelli di template e typedef, non è troppo difficile da immaginare). Quindi, se intendi uno static_cast, scrivine uno e ottieni un errore in fase di compilazione, ti verrà detto immediatamente che i tipi coinvolti non sono quelli che pensavi di essere. Con l'atteggiamento "tutto va bene" del cast in stile C, non scoprirai l'errore nel tempo.

Aiuta anche con compatibilità futura. Se i tipi coinvolti nel cast cambiano più avanti nello sviluppo, uno static_cast segnalerà un errore in cui un cast di tipo C cambierebbe semplicemente il suo comportamento (in modo molto probabilmente non voluto).

+0

"Con il cast in stile C non scoprirò l'errore nel tempo" - non vale solo per il lancio tra i puntatori? Puoi dare un esempio non puntatore di questo reclamo? –

+0

@barakmanos Intendevo questo paragrafo come "sei convinto al 1000% che stai trasmettendo numeri interi, ma uno di questi è davvero un puntatore." Modificato per chiarire. – Angew

+1

O per dirla in un altro modo, l'uso di 'static_cast' consente di applicare questo vincolo desiderabile, che il tipo di origine non è un puntatore. 'int * ip = new int(); long j = static_cast (* ip); 'è un esempio stupido, ma scrivendolo in questo modo si cattura l'errore di digitare' ip' per '* ip', mentre' long (* ip) 'non lo cattura perché' long (ip) 'è un cast in stile C valido. –

5

è statico_cast utilizzato per i tipi non puntatore solo al fine di mantenere la coerenza di codifica?

No (beh, sì, ma non solo).

È anche facile da trovare/sostituire. Questo è importante in caso di refactoring, bug fixing, ecc.

È un vincolo sul tipo di cast consentito: si consideri un esempio in cui si ha un cast di tipo C (che funziona bene) su una variabile, quindi si cambia la dichiarazione della variabile casted, a qualcosa che rende non valido il cast (ad esempio, si modifica int x; in void * const x;).

Il cast di tipo C esegue improvvisamente un'altra funzione (ad esempio const_cast<...>(reinterpret_cast<...>(...)) con lo stesso codice.

Se si scrive il codice iniziale con un static_cast invece di un cast in stile C, il compilatore ti comunicherà che static_cast non sta eseguendo un cast statico.

+0

Sì, trovare/sostituire mi è venuto in mente poche ore dopo aver posto questa domanda. Grazie. –

Problemi correlati