2012-08-01 17 views
8

Dalla documentazione cpp per std::vector, vedo questo:C++ STL vettoriale: push_back prendendo riferimento

void push_back (const T& x); 

Capisco che push_back fa una copia dell'oggetto che mi passa. Ma, perché è la firma const T& ? Guardando a questo, inizialmente ho pensato che ci vuole un riferimento const di qualsiasi oggetto che spingo allo vector.

+0

Lo farò. L'ho capito solo ieri e lo faccio da quel momento in poi. Grazie! – sachin2182

risposta

12

L'altra opzione sarebbe

void push_back(T x); 

che è, prendendo x per valore. Tuttavia, ciò comporterebbe (in C++ 03) la creazione di una copia aggiuntiva di x (la copia negli argomenti su push_back). Prendendo x di riferimento const evita questo.

Guardiamo lo stack per una chiamata v.push_back(T()) presi per valore:

v.push_back(T());      // instance of T 
void std::vector<T>::push_back(T x) // copy of T 
new (data_[size_ - 1]) T(x)   // copy of copy of T 

Prendendo come riferimento const otteniamo:

v.push_back(T());        // instance of T 
void std::vector<T>::push_back(const T &x) // const reference to T 
new (data_[size_ - 1]) T(x)     // copy of T 

In C++ 11 sarebbe possibile (anche se non necessario) per prendere x in base al valore e utilizzare std::move per spostarlo sul vettore:

v.push_back(T());        // instance of T 
void std::vector<T>::push_back(T x)   // copy of T 
new (data_[size_ - 1]) T(std::move(x))  // move the copy of T 
+1

È comunque preferibile avere 'T const &' in C++ 11 (insieme a un sovraccarico' T &&'), poiché non tutti gli oggetti possono essere spostati in modo efficiente. –

7

Il numero object viene passato per riferimento per evitare extra copy. Quindi una copia viene inserita nello vector.

7

Giusto per chiarire la "copia extra" che descrive @ecatmur, se push_back ha ricevuto il suo argomento in base al valore, ciò che accadrebbe sarebbe che avresti iniziato con il tuo oggetto. Una copia di questo sarebbe passata a push_back come parametro. Quindi push_back creerebbe una copia di che inserisca nel vettore stesso.

Poiché la reale implementazione di push_back riceve il suo argomento per riferimento, questa (push_back) crea il nuovo oggetto nel vettore direttamente come una copia dell'oggetto originale.

Come già accennato, sì, con C++ 11 usando la semantica del movimento, sarebbe possibile (anche se probabilmente non particolarmente vantaggioso) passare l'argomento per valore, e quindi spostare il valore da tale argomento nel nuovo oggetto in il vettore. Se quello che stavi inserendo nel vettore era, per esempio, una stringa che per lo più contiene solo un puntatore e un paio di campi "bookkeeping" (quantità di memoria allocata, quantità di memoria attualmente in uso), sarebbe quasi come efficiente come passare un riferimento, perché una mossa può semplicemente fare una copia superficiale - copiare il puntatore e il libro mantenendo i valori stessi, invece di tutti i dati a cui punta. Se, tuttavia, l'oggetto in questione contenesse direttamente tutti i suoi dati (cioè non un puntatore), allora una mossa sarebbe lenta quanto una copia.

passaggio per riferimento, evita tutto che la copia, quindi, anche per qualcosa di simile a una corda, è generalmente più veloce ancora (per un caso come questo che l'oggetto originale non può essere invalidata). Ha anche il minor vantaggio di lavorare con C++ 98/03, non solo C++ 11.