2009-11-07 12 views
10

So che i contenitori STL come vector copia l'oggetto quando viene aggiunto. push_back metodo assomiglia:In che modo i contenitori STL copiano oggetti?

void push_back (const T& x); 

Sono sorpreso di vedere che ci vuole l'elemento come di riferimento. Ho scritto un programma di esempio per vedere come funziona.

struct Foo 
{ 
    Foo() 
    { 
     std::cout << "Inside Foo constructor" << std::endl; 
    } 

    Foo(const Foo& f) 
    { 
     std::cout << "inside copy constructor" << std::endl; 
    } 
}; 

Foo f; 
std::vector<Foo> foos; 
foos.push_back(f); 

Questo copia l'oggetto e posso vederlo sta chiamando costruttore di copia.

La mia domanda è, quando il push_back prende l'elemento come riferimento, come chiama il costruttore di copia? O mi sto perdendo qualcosa qui?

Qualche idea ..?

risposta

12

Probabilmente utilizza "posizionamento new" per costruire l'oggetto sul posto nel suo array interno. Il posizionamento new non assegna alcuna memoria; posiziona semplicemente l'oggetto dove si specifica e chiama il costruttore. La sintassi è new (address) Class(constructor_arguments).

Il costruttore di copia T::T(T const &) viene chiamato per creare la copia sul posto. Qualcosa di simile a questo (semplificato):

template<T> 
void vector<T>::push_back(T const &item) { 
    // resize if necessary 
    new (&d_array[d_size++]) T(item); 
} 

noti che T deve avere un costruttore di copia per questo al lavoro. Di default (se non fai nulla), ne ottiene uno gratis. Se lo definisci esplicitamente, deve essere public per vector<T> per funzionare.

Here's how GNU's libstdc++ does it, ma dubito che sarà molto illuminante. Esiste un allocatore (il secondo argomento del modello su vector) che lo rende meno semplice.

+0

Questo è OK quando T ha un costruttore senza parametri. Ma cosa succederà quando avrà un costruttore parametrizzato? In che modo il vettore può inizializzare un nuovo oggetto? –

+0

Questo è OK quando T ha un _copy constructor_. Il che è, per impostazione predefinita, e se lo si implementa, a meno che non lo si sia reso esplicitamente 'private' o' protected'. – Thomas

+0

Ho modificato la mia risposta per chiarire. – Thomas

1

Usa il posizionamento nuovo operatore e lo copia-costruisce in memoria unitaria;

Il posizionamento new crea un nuovo elemento in corrispondenza di un indirizzo specificato in memoria, nel caso vettoriale, la fine corrente();

void push_back(const T& val){ 
::new (&*end()) T(val); 
[increase end] 
} 

sguardo http://spotep.com/dev/devector.h che ha il codice del tutto evidente (al contrario di maggior parte delle implementazioni STL).

3

L'SDK C++ richiede sempre const T & come parametro di funzione per l'efficienza.

Nel tuo caso, se ci vuole T come parametro, l'azione di copiatura sarà fatto due volte, una per il passaggio di assicurarne il funzionamento push_back(f), una per interni aggiungerlo al contenitore. E prendendo const T& come parametro è necessaria solo una copia!

+7

Non esiste un SDK C++. – GManNickG

+0

ok, intendo le cose di fondo come le specifiche del linguaggio C++, STL ecc ... – learner

Problemi correlati