2009-11-07 8 views
10

Sé que los contenedores STL como vector copian el objeto cuando se agrega. push_back método se parece a:¿Cómo copian los objetos STL los contenedores?

void push_back (const T& x); 

me sorprende ver que se necesita el artículo como referencia . Escribí un programa de muestra para ver cómo funciona.

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); 

Esto copia el objeto y puedo ver que está llamando constructor copia.

Mi pregunta es, cuando el push_back toma de artículo como referencia, la forma en que está llamando al constructor de copia? ¿O me estoy perdiendo algo aquí?

¿Alguna idea ...?

Respuesta

12

Probablemente utiliza "colocación new" para construir el objeto en el lugar en su matriz interna. La ubicación new no asigna memoria; simplemente coloca el objeto donde especifica y llama al constructor. La sintaxis es new (address) Class(constructor_arguments).

El constructor de copia T::T(T const &) está llamado a crear la copia en el lugar. Algo como esto (simplificado):

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

Tenga en cuenta que T debe tener un constructor de copia para que esto funcione. Por defecto (si no hace nada), obtiene uno gratis. Si lo define explícitamente, debe ser public para vector<T> para funcionar.

Here's how GNU's libstdc++ does it, pero dudo que va a ser muy esclarecedor. Hay un asignador (el segundo argumento de plantilla para vector) que lo hace menos directo.

+0

Esto está bien cuando T tiene un constructor sin parámetros. Pero, ¿qué pasará cuando tenga un constructor parametrizado? ¿Cómo el vector puede inicializar un nuevo objeto? –

+0

Esto está bien cuando T tiene un _copy constructor_. Que es lo que hace, por defecto, y si lo implementa, a menos que explícitamente lo haga 'private' o' protected'. – Thomas

+0

Edité mi respuesta para aclarar. – Thomas

1

Utiliza el nuevo operador de colocación y lo copia a la memoria unificada;

La colocación nueva crea un nuevo elemento a la dirección especificada en la memoria, en el caso del vector, el extremo corriente();

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

vistazo a http://spotep.com/dev/devector.h que tiene el código bastante claro (a diferencia de la mayoría de las implementaciones STL).

3

El C++ SDK siempre toma const T & como parámetro de la función para la eficiencia.

En su caso, si se necesita T como parámetro, la acción de copia se hará dos veces, una para pasar a funcionar push_back(f), uno para uso en interior de añadirlo al contenedor. Y tomando const T& como parámetro ¡solo se necesita una copia!

+7

No hay SDK de C++. – GManNickG

+0

ok, me refiero a las cosas de fondo como la especificación del lenguaje C++, STL ect ... – learner

Cuestiones relacionadas