2013-04-03 9 views
6
class foo { 
    public: 
    friend ostream& operator << (ostream &os, const foo &f); 
    foo(int n) : a(n) {} 
    private: 
    vector <int> a; 
}; 

ostream& operator << (ostream &os, const foo &f) { 
    for (int i = 0; i < f.a.size(); ++i) 
     os << f.a[i] << " "; 
    os << endl; // why is this line a must? 
} 

int main(void) { 
    foo f(2); 
    cout << f << endl; 
    return 0; 
} 

Nel codice di cui sopra, se la linea marcata viene rimosso, ci sarà un errore di segmento, qualcuno può spiegare perché?sovraccaricato ostream colpa dell'operatore di segmentazione se non endl

+1

Perché nessuno mai si preoccupa di controllare il codice in questione? Il compilatore avrebbe dovuto avvertirti di tale errore - "... avviso: nessuna dichiarazione di ritorno in funzione che restituisce non vuoto [-Wreturn-type]" Vedi http://liveworkspace.org/code/2ygK20$1 } ^ – SChepurin

risposta

16
ostream& operator << (ostream &os, const foo &f) { 
    for (int i = 0; i < f.a.size(); ++i) 
     os << f.a[i] << " "; 
    os << endl; // why is this line a must? 
} 

non è manadatory. Il segfault è causato perché non stanno tornando os

ostream& operator << (ostream &os, const foo &f) { 
    for (int i = 0; i < f.a.size(); ++i) 
     os << f.a[i] << " "; 
    return os; // Here 
} 

è un comportamento indefinito se non restituire l'ostream. Lo endl sta scaricando il tuo os qui. Ecco perché sembra che funzioni.

EDIT: Perché si sta lavorando in questo caso secondo Bo Persson

il sistema operativo < < endl; è un'altra chiamata operatore che in realtà restituisce il sistema operativo tramite inserendolo "dove è previsto un valore di ritorno" (probabilmente un registro). Quando il codice restituisce un altro livello al principale, il riferimento al sistema operativo è ancora lì

+0

È l'implicito 'int' (?) che verrebbe restituito se non viene specificato nulla o il suo valore è in qualche modo standardizzato? –

+4

Non vi è alcun 'implicato' restituito qui. È chiaramente specificato come restituire 'ostream &'. Quindi, senza una dichiarazione "return", si ottiene che qualunque junks si trovi nel posto giusto nello stack dopo la funzione. Succede solo che con 'os << endl' lì, quella spazzatura è qualcosa che non causa un crash. – BoBTFish

+2

@honk Non c'è implicito 'int' in C++. Non riuscire a restituire qualcosa da una funzione non-'void 'è semplicemente un comportamento non definito, punto. – Angew