2009-12-23 22 views
5

Ho incontrato questo codiceE commerciale all'interno colata

int n1 = 10; 
int n2 = (int &)n1; 

Non capisco il significato di questo casting, n2 non è di riferimento in quanto la modifica n1 non riflette n1. Stranamente questo codice genera l'errore del compilatore in gcc dove si compila bene in VC++.

Qualcuno conosce il significato di questo casting?

+0

Il mio C++ è arrugginito, ma penso che a * possa essere usato per allocare un int o avere una serie di int. Sono in perdita per ciò che il & vorrà dire in questo caso però. –

+2

Qual è il tipo di n1? –

+0

"la modifica di n1 non riflette n1" ?? –

risposta

9

Supponendo n2 è di qualche tipo built-in, il cast al tipo int & esegue la reinterpretazione di lvalue n1 (qualunque sia il tipo che aveva) come valore assegnabile di digitare int.

Nel contesto di int n2 = (int &) n1 dichiarazione, se n1 è di per sé un lvalue di tipo int, il cast è superfluo, cambia assolutamente nulla. Se n1 è un lvalue di tipo const int, allora il cast cancella semplicemente la costanza, che è anche superflua nel contesto di cui sopra. Se n1 è un Ivalue di un altro tipo, il cast semplicemente rilegge memoria occupata da n1 come un oggetto di tipo int (questo è chiamato tipo punning). Se n1 non è un lvalue il codice è mal formato.

Così, nel codice come int n2 = (int&) n1 il cast int & solo non ridondante (ha qualche effetto reale) quando esso tipo gioco di parole, cioè quando n1 è un Ivalue di qualche altro tipo (non int). Per esempio

float n1 = 5.0; 
int n2 = (int &) n1; 

che sarebbe equivalente a

int n2 = *(int *) &n1; 

e

int n2 = *reinterpret_cast<int *>(&n1); 

Inutile dire che questa è una pratica di programmazione piuttosto male.

Questo è, BTW, uno dei casi in cui si utilizza un cast in stile C++ dedicato è fortemente preferito. Se l'autore del codice utilizzava reinterpret_cast anziché il cast in stile C, probabilmente non dovresti fare questa domanda.

Ovviamente, se n1 è di tipo int, non c'è spiegazione significativa per questo cast. In tal caso è, di nuovo, del tutto superfluo.

P.S. C'è anche la possibilità che n2 sia una classe con operatore di conversione sovraccarico sul tipo int &, che è una storia completamente diversa ... Comunque, devi dire cosa è n2 quando fai domande del genere.

11

Questo è perfettamente codice C++ e si compila con g ++ 4.4.1. Crea un riferimento temporaneo a n1 e quindi utilizza il valore indicato da quel riferimento per inizializzare n2.

Questo può essere più facile da vedere se expresed in funzione:

void f(int & n1) { 
    int n2 = n1; // initialise with valuue referred to by n1 
} 

notare che questo non è il codice C valido, in quanto C non supporta i riferimenti.

+0

Direi che in questo contesto è solo "prefetto" valido nelle situazioni in cui è superfluo, cioè quando 'n1' stesso ha tipo' int'. Quando non è superfluo, è un 'reinterpret_cast'. Di solito quando è necessario reinterpretare la memoria occupata da un altro oggetto, il codice risultante potrebbe essere sintatticamente valido, ma lontano dall'essere perfetto, per così dire. – AnT

+0

Devo ammettere, ho pensato che n1 fosse un int. A meno che non risparmi l'OP, forse non lo sapremo mai ... –

+1

Cos'è un "riferimento temporaneo"? –

0

Compilare anche in gcc (ho provato solo per essere sicuro). Semplicemente trasmette n1 a un riferimento.

1

Credo che sia probabilmente un errore di battitura nel codice originale.

GCC è solitamente più pedante di VC++. Tuttavia questo codice sembra buono anche se sta facendo cose inutili. Fondamentalmente viene creato un riferimento temporaneo per n1 e quindi viene utilizzato il costruttore di copie per istanziare n2.

+0

operator =, sicuramente? E se così fosse, ti sbaglieresti. Il codice mostra un'inizializzazione, non un compito: sono cose diverse in C++. –

+0

Vero, correggere la risposta. – rui

+0

'n2' ha tipo' int'. Digitare 'int' non è un tipo di classe. Non ha costruttore di copie. Non ha costruttori. – AnT

2
int main() 
{ 
     int n1 = 10; 
     int n2 = (int &)n1; 
     cout<<n2<<endl; 
} 

Stampa 10 come previsto.
Non ci sono problemi con il cast.
Si crea solo un punto di riferimento temporaneo come suggerito dal uscita successiva:

int main() 
{ 
     int n1 = 10; 
     int n2 = (int &)n1; 
     n2 = 20; 
     cout<<n1<<endl; // print 10 and not 20. 
} 
+0

Quindi, come è diverso da "int n2 = n1"? –

1

Si fa la cosa più ovvia. Trasmettere n1 a un riferimento int e quindi assegnarlo a int n2.

E supponendo che n1 sia un int, dovrebbe essere compilato correttamente.

Non verrà compilato se n1 è un valore. Quanto segue non si compila, per esempio:

(int&)foo(); 
(int&)42; 
(int&) (x+y); // assuming x and y are int variables 
+0

L'ultimo si compila perfettamente bene. Il cast ha una precedenza più alta dell'aggiunta. '(int &) x + y' significa' ((int &) x) + y'. – AnT

+0

Vero. Risolto ora :) – jalf