2011-09-23 11 views
16

El código folowing muestra que no se espera una salida:¿STL Vector llama a un destructor de un objeto no asignado?

class test 
{ 
    public: 
    test() 
    { 
     std::cout << "Created" << (long)this << std::endl; 
    } 
    ~test() 
    { 
     std::cout << "Destroyed" << (long)this << std::endl; 
    } 
}; 

int main(int argc, char** argv) 
{ 
    std::vector<test> v; 
    test t; 
    v.push_back(t); 

    return EXIT_SUCCESS; 
} 

Cuando ejecuta muestra:

Created-1077942161 
Destroyed-1077942161 
Destroyed674242816 

creo que la segunda salida "Destroyed" no debería estar allí. Cuando no uso el vector, el resultado es una línea Creada y otra Destruida como se esperaba. ¿Es este comportamiento normal?

(Esto se compila con GCC en un sistema FreeBSD)

+3

+1 para [SSCCE] (http://sscce.org/) – Flexo

+3

Para imprimir punteros es mejor lanzar al puntero void: 'std :: cout << (void *) this << std :: endl ; '. –

+0

También devolver 'EXIT_SUCCESS' es opcional. Puede omitir el valor de retorno en 'main', devolverá' 0' (que se convertirá en el número que signifique "terminación normal" para su plataforma) –

Respuesta

31

Todo es como debe ser: no hay la variable local t, que se crea y destruye a continuación al final de main(), y hay v[0], que recibe creado y destruido al final de main().

No ve la creación de v[0] porque eso sucede mediante el constructor copiar o mover, que su clase de prueba no proporciona. (Así el compilador proporciona una para ti, pero sin salida.)


Para propósitos de prueba es útil para escribir por sí mismo una vez por todas una clase de prueba que contiene todos los posibles constructores, destructores, misiones y los operadores de swap e imprime una línea de diagnóstico en cada una, para que pueda presenciar cómo se comportan los objetos cuando se utilizan en contenedores y algoritmos.

+0

No puede ser 'move constructor'. – Nawaz

+0

@Namaz: Correcto. Para usar el constructor de movimientos, debería decir eitehr 'v.push_back (std :: move (t))', o 'v.push_back (test())'. Sin embargo, ambos crearían una secuencia similar de mensajes. –

29
#include <cstdlib> 
#include <vector> 
#include <iostream> 

class test 
{ 
    public: 
    test() 
    { 
     std::cout << "Created " << (long)this << std::endl; 
    } 
    test(const test&) 
    { 
     std::cout << "Copied " << (long)this << std::endl; 
    } 
    ~test() 
    { 
     std::cout << "Destroyed " << (long)this << std::endl; 
    } 
}; 

int main(int argc, char** argv) 
{ 
    std::vector<test> v; 
    test t; 
    v.push_back(t); 

    return EXIT_SUCCESS; 
} 

Salida:

Created -1076546929 
Copied 147865608 
Destroyed -1076546929 
Destroyed 147865608 

std::vector::push_back copia el objeto t, se puede ver el constructor de copia se invoca por el código de seguridad.

2

El vector contiene una copia de t, por lo tanto, después de la llamada al push_back, tiene dos versiones de t ... una en la pila y otra en el vector. Como la versión vectorial fue creada por un copia-construtor, usted no ve un mensaje de "Creado ..." para ese objeto ... pero aún debe ser destruido cuando el contenedor vectorial se sale del alcance, por lo tanto usted obtiene dos "Destruido ..." mensajes.

Cuestiones relacionadas