2012-03-04 15 views
14

Ho una domanda C++ completamente di base qui.Come avviene il concatenamento dell'operatore in C++?

#include <iostream> 
using namespace std; 

int main() { 
    int a = 255; 
    cout << hex << a << endl; // <----- 
} 

Nel pezzo codice di cui sopra, come è incatenato la dichiarazione std::cout?

Sono consapevole che un'implementazione di cout ritornerebbe il riferimento cout oggetto per consentire concatenamento accada, quindi deve essere eseguito come:

(((cout << hex) << a) << endl) 

cioè equivalente a questi, al fine

  1. cout << hex
  2. cout << a
  3. cout << endl

Ma questo non può essere il caso perché in qualche modo il valore di a ha bisogno di essere convertito in hex forma!

In che modo gli operatori sono concatenati dal compilatore per rendere possibile la conversione?

risposta

7

Ecco come hex di solito è implementato:

inline ios_base& 
hex(ios_base& __base) 
{ 
    __base.setf(ios_base::hex, ios_base::basefield); 
    return __base; 
} 

Come si può vedere, hex non esegue alcuna conversione da solo: invece, imposta un'opzione nel flusso di base da utilizzare esadecimale per la stampa di i numeri vi sono passati in un secondo momento.

EDIT (in risposta a un commento)

Come Hammar osserva correttamente, l'altra parte del puzzle è come hex(ios_base& __base) viene chiamato. C'è un sovraccarico dell'operatore << con questa firma:

ostream& operator <<(ostream& (*)(ostream&)) 

Questo sovraccarico è essenziale dettaglio di implementazione di stream manipulators. È questo sovraccarico che chiama lo hex e lascia che faccia la sua "magia" (che ovviamente non dovrebbe più sembrare magica per te).

+1

Probabilmente dovresti anche menziona l'altra parte del puzzle, il sovraccarico di 'ostream & operator << (ostream & (*) (ostream &)), che è il modo in cui vengono chiamati i manipolatori come' hex'. – hammar

+0

@hammar Ottima osservazione! Grazie mille per il commento, ho modificato la risposta per riflettere questo punto essenziale. – dasblinkenlight

22

Hai capito bene, è esattamente come funziona. hex ha solo un tipo speciale che cambia lo stato interno dell'oggetto cout quando passata alla sua funzione operator<<. Lo stato interno determina quindi come vengono trattati i valori futuri passati a cout tramite operator<<.

std::hex sembra essere una funzione. cout << hex non chiama la funzione esadecimale come tale, tuttavia: passa un puntatore alla funzione esadecimale a un sovraccarico operator<< per ostream che accetta i puntatori di funzione con una particolare firma. hex() viene quindi chiamato dall'interno dell'implementazione dell'operatore tramite quel puntatore di funzione e modifica l'oggetto ostream da lì per quanto ne so.

+0

'hex' non è un * tipo speciale *. È una funzione (o semplicemente dicendo che 'hex' * ha * un tipo speciale, non ha senso. Cosa significa * ha * significa qui?) – Nawaz

+1

Sì, capita di avere un tipo di funzione. È il tipo che determina quale overload dell'operatore viene chiamato, però. 'cout << hex' non chiama la funzione' hex' come tale: passa un puntatore alla funzione esadecimale a un overload 'operator <<' che accetta i puntatori di funzione con una particolare firma. 'hex()' viene quindi chiamato dall'interno dell'implementazione dell'operatore, per quanto ne so. – pmdj

+0

+1. Ora la risposta sembra migliore. – Nawaz

2

std::hex imposta effettivamente un flag all'interno dell'oggetto std::cout, che rimane attivo fino al ripristino di IIRC. Gli stessi operator<< vengono valutati da sinistra a destra, quindi i tuoi paren sono corretti.

1

Dal mio punto di vista hex è solo un oggetto pacchetto che ha un effetto collaterale sull'oggetto cout. Dopo questo cout mostrerà solo valori esadecimali.

Problemi correlati