Qual è la differenza tra static_cast <> e il casting in stile C?


Risposte:


217

I cast in stile C ++ vengono controllati dal compilatore. I cast in stile C non sono e possono fallire in fase di esecuzione.

Inoltre, i cast in stile c ++ possono essere cercati facilmente, mentre è davvero difficile cercare i cast in stile c.

Un altro grande vantaggio è che i 4 diversi cast in stile C ++ esprimono più chiaramente l'intento del programmatore.

Quando scrivo C ++, userei quasi sempre quelli C ++ rispetto allo stile C.


67
Gli unici cast che possono fallire in fase di esecuzione sono dynamic_casts.
R. Martinho Fernandes,

12
C ++ reinterpret_cast <T> (U) può fallire in fase di esecuzione più o meno allo stesso modo dei cast in stile C, e sono tutti abbastanza diversi dal modo in cui dynamic_cast <T> (U) fallisce.
Christopher Smith,

20
˗1 cast normale in C (int)somethingnon può fallire - si ottiene cast per int o errore del compilatore.
Tomáš Zato - Ripristina Monica il

2
Puoi spiegare perché i cast C ++ possono essere cercati più facilmente dei cast C?
Minh Tran,

3
@MinhTran Per lo stile C ++ puoi cercare la parola chiave "cast" attraverso i tuoi file sorgente. Ma vuoi fare con i cast in stile c?
Huangzonghao,

176

In breve :

  1. static_cast<>() ti dà la possibilità di compilare il tempo di verifica, il cast di C-Style no.
  2. static_cast<>() è più leggibile e può essere individuato facilmente ovunque all'interno di un codice sorgente C ++, il cast di C_Style non è.
  3. Le intenzioni vengono trasmesse molto meglio usando i cast C ++.

Più spiegazione :

Il cast statico esegue conversioni tra tipi compatibili . È simile al cast in stile C, ma è più restrittivo. Ad esempio, il cast in stile C consentirebbe a un puntatore intero di puntare a un carattere.

char c = 10;       // 1 byte
int *p = (int*)&c; // 4 bytes

Poiché ciò comporta un puntatore a 4 byte (un puntatore al tipo di dati a 4 byte) che punta a 1 byte di memoria allocata, la scrittura su questo puntatore provocherà un errore di runtime o sovrascriverà della memoria adiacente.

*p = 5; // run-time error: stack corruption

Contrariamente al cast in stile C, il cast statico consentirà al compilatore di verificare la compatibilità dei tipi di dati puntatore e puntatore, il che consente al programmatore di rilevare questa assegnazione errata del puntatore durante la compilazione.

int *q = static_cast<int*>(&c); // compile-time error

Puoi anche controllare questa pagina per ulteriori spiegazioni sui cast C ++: fai clic qui


17
Penso che invece di "puntatore a 4 byte" intendevi "puntatore al tipo di dati a 4 byte"
iheanyi,

ma consente int q = static_cast <int> (c);
TonyParker,

3
@TonyParker Questo perché non c'è niente di sbagliato in quella linea.
Braden Best

15

Vedi Un confronto tra gli operatori di casting C ++ .

Tuttavia, l'utilizzo della stessa sintassi per diverse operazioni di casting può rendere poco chiaro l'intento del programmatore.

Inoltre, può essere difficile trovare un tipo specifico di cast in una base di codice di grandi dimensioni.

la generalità del cast in stile C può essere eccessiva per le situazioni in cui tutto ciò che serve è una semplice conversione. La possibilità di selezionare tra diversi operatori di casting con diversi gradi di potenza può impedire ai programmatori di lanciare inavvertitamente un tipo errato.


14
struct A {};
struct B : A {};
struct C {}; 

int main()
{
    A* a = new A;    

    int i = 10;

    a = (A*) (&i); // NO ERROR! FAIL!

    //a = static_cast<A*>(&i); ERROR! SMART!

    A* b = new B;

    B* b2 = static_cast<B*>(b); // NO ERROR! SMART!

    C* c = (C*)(b); // NO ERROR! FAIL!

    //C* c = static_cast<C*>(b); ERROR! SMART!
}

5
Potresti per favore elaborare di più la tua risposta aggiungendo un po 'più di descrizione sulla soluzione che offri?
abarisone,

1
Penso che la risposta mostri che "static_casts" controlla le conversioni di tipo per assicurarsi che siano lungo percorsi validi nel grafico della gerarchia. In questo esempio particolare, è consentito il cast da A * a B * o da B * a A * poiché A e B formano un percorso nel grafico gerarchico. C * non è sul percorso, quindi static_cast produrrà un errore di compilazione. Sidenote: potrebbe valere la pena notare che il casting da A * a B * può comportare NULL con un Dynamic_cast in fase di esecuzione a seconda del vero oggetto sottostante.
Tommy Chen,

7

Un ottimo post che spiega diversi cast in C / C ++ e cosa fa realmente il cast in stile C: https://anteru.net/blog/2007/12/18/200/index.html

Casting in stile C, usando la sintassi della variabile (tipo). Il peggio mai inventato. Questo tenta di eseguire i seguenti cast, in questo ordine: (vedi anche C ++ Standard, 5.4 expr.cast paragrafo 5)

  1. const_cast
  2. static_cast
  3. static_cast seguito da const_cast
  4. reinterpret_cast
  5. reinterpret_castSeguito da const_cast

5

static_castcontrolla al momento della compilazione che la conversione non sia tra tipi ovviamente incompatibili. Al contrario dynamic_cast, nessun controllo per la compatibilità dei tipi viene eseguito in fase di esecuzione. Anche,static_cast conversione non è necessariamente sicura.

static_cast viene utilizzato per convertire da puntatore a classe base in puntatore a classe derivata o tra tipi nativi, come enum in int o float in int.

L'utente di static_cast deve assicurarsi che la conversione sia sicura.

Il cast in stile C non esegue alcun controllo, né in fase di compilazione né in fase di esecuzione.


3

Poiché esistono diversi tipi di casting, ciascuno con una semantica diversa, static_cast <> ti consente di dire "Sto facendo una conversione legale da un tipo a un altro" come da int a double. Un semplice cast in stile C può significare molte cose. Sei su / giù casting? Stai reinterpretando un puntatore?

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.