2009-12-26 21 views
5

Sto imparando C++ al momento, C++ Primer plus. Ma mi sono semplicemente sentito come controllare il sito Web cplusplus e saltare un po 'in avanti verso la gestione dei file.'Inizializzazione bretelle'. (C++)

Conosco praticamente le basi della gestione dei file provenienti da java, php, visual basic. Ma mi sono imbattuto in una linea piuttosto strana.

ostream os(&fb); 

fb rappresenta un filebuf. Io proprio non capisco la sintassi di questo, ma posso capire che è lo stesso di:

ostream os = &fb; 

Ma non ho mai letto su questo modo di inizializzazione delle variabili.

Quindi mi chiedo. Sono solo privo di senso e mi manca una funzione utile per tutto il tempo? Questo modo di inizializzare è solo vecchio? È qualcosa di diverso?

Grazie in anticipo.

risposta

5

Forse si dovrebbe leggere this e this

+0

Grazie per questo ottimo riferimento e risposta rapida :) –

+5

Dovresti fornire la risposta qui, in questo post. Il link potrebbe essere inattivo quando qualcun altro ha bisogno di rispondere a questa domanda, e hey, se vuoi il rappresentante, dovresti pubblicare la risposta effettiva. È comune, quindi, cortesia. – jalf

+0

Parafrasato leggermente dal secondo link: 'ostream os = &fb;' è inizializzazione della copia, e 'os' è sempre inizializzato usando il copyctor di' ostream'. (Il "=" è solo un salto di sintassi da C; operator = non viene mai chiamato.) Il compilatore è effettivamente consentito (ma non richiesto) per ottimizzare la costruzione della copia in questo tipo di situazione. Se lo ottimizza, il copy ctor deve essere ancora accessibile. ** Linea guida: ** Preferisco usare il modulo 'ostream os (& fb)'. Funziona sempre dove 'ostream os = & fb' funziona e ha altri vantaggi (ad esempio, può richiedere più parametri). –

5

Un piccolo programma per vedere quando costruttore di copia viene chiamato e quando la funzione operatore di assegnamento si chiama:

#include <iostream> 

using namespace std; 

class test 
{ 
    public: 
     // default constructor. 
     test() 
     { 
      cout<<"Default Ctor called"<<endl; 
     } 

     // copy constructor. 
     test(const test& other) 
     { 
      cout<<"Copy Ctor called"<<endl; 
     } 

     // overloaded assignment operator function. 
     test& operator=(const test& other) 
     { 
      cout<<"Overload operator function called"<<endl; 
      return *this; 
     } 
}; 

int main(void) 
{ 
    test obj1; // default constructor called. 

    test obj2 = obj1; // copy constructor called. 

    test obj3(obj2); // again copy constructor called. 

    obj1 = obj2; // overloaded assignment operator function. 

    return 0; 
} 

uscita:

Default Ctor called 
Copy Ctor called 
Copy Ctor called 
Overload operator function called 

Quindi nel tuo caso, il costruttore di copie di ostream viene chiamato in entrambe le occasioni.

+0

Sembra che fossi piuttosto corretto allora: D. Grazie per la chiara spiegazione. Buone vacanze! –

6

Entrambe le forme eseguono l'inizializzazione . La prima sintassi (con ()) è chiamata sintassi di inizializzazione diretta. La seconda sintassi (con =) è chiamata sintassi di inizializzazione della copia. Agiranno nello stesso modo nella maggior parte dei casi reali, ma ci sono davvero differenze tra i due.

Nelle situazioni in cui tipi sul lato sinistro (LHS) e destra (RHS) sono identici (ignorando eventuali const/qualificatori volatili), entrambi sono infatti esattamente lo stesso. Il linguaggio standard afferma esplicitamente che in questo caso il modulo = equivale a () modulo.

Ma quando i tipi sono diversi (e il tipo LHS è un tipo di classe), queste due forme generalmente funzioneranno in modo diverso.

  • La forma copia-inizializzazione funziona come segue: convertire il valore RHS all'oggetto temporaneo di tipo LHS (con ogni mezzo possibile: conversione standard, operatore di conversione, costruttore conversione). Quindi utilizzare il costruttore di copia della classe LHS per copiare l'oggetto temporaneo sull'oggetto LHS.

  • Il modulo di inizializzazione diretta funziona come segue: è sufficiente prendere in considerazione tutti i costruttori di LHS e scegliere quello più appropriato utilizzando la risoluzione di sovraccarico.

È possibile nota subito che la sintassi copia-inizializzazione utilizza incondizionatamente il costruttore di copia (la copia e il temporaneo intermedio può essere ottimizzata via, ma concettualmente sono lì).Se la classe LHS non ha un copy-constructor accessibile, l'inizializzazione della copia diventa incondizionatamente mal formata, mentre l'inizializzazione diretta potrebbe ancora funzionare.

Inoltre, la parola chiave explicit applicata a un determinato costruttore influirà sulla forma di inizializzazione disponibile per le combinazioni di tipi.

+1

Solo andando a scegliere quella parola * esattamente * (poiché la risposta suona come se fosse una risposta davvero standard): Se il costruttore di copie è esplicito, la sintassi '=' fallirà nel caso LHR e RHS siano uguali digita, mentre il form '()' non fallirà. –

0

Dalla mia comprensione, & var è un alias per la variabile var e non importa quale si utilizza.

-------- aggiunta -----------------

Il codice di seguito è tratto dal Stroustrup book.From questo suo chiaro che entrambi sono alias della stessa variabile. Dice anche come sotto.

"La semantica dell'argomento passata è definita come quella di inizializzazione, quindi quando viene chiamato, l'argomento di incremento aa diventa un altro nome di x." Ecco perché mi sono riferito a & x per essere alias di x.

void increment(int& aa) { aa++; }

void f() { int x = 1; increment(x); }

+0

No, '& var' è l'indirizzo di' var'. Hanno diversi tipi; se var è di tipo T, allora & var è di tipo T *. –

+0

Ho modificato la mia risposta. per favore controllalo. – Boolean

1

Un importante vantaggio di inizializzazione funzione di chiamata è che funzionano anche con i costruttori che prendono più argomenti. Ad esempio, un costruttore fstream può assumere due parametri:

std::fstream file("filename", ios_base::out); 

Fino C++0x uniform initialization è ampiamente disponibile, inizializzazione chiamata di funzione è l'unico modo per gestire più costruttori argomento.