2009-10-28 24 views
6

Encontré un uso extraño del destructor mientras trabajaba en una biblioteca existente. El destructor de un vector stl asignado a la pila se llamaba explícitamente, cuando es el caso de que ese objeto deba volver a utilizarse. Estos objetos vectoriales son una versión ligeramente personalizada de la clase de vector stl que tiene un método especializado clear. En el cuerpo del destructor existen dos llamadas al método: clear(), _Tidy().Objeto asignado a la pila de C++, llamada al destructor explícito

He estado tratando de pensar en una buena razón por la que se llama a este destructor en lugar de simplemente clear pero estoy perdido. ¿Alguien arrojó alguna luz sobre por qué esto puede ser una buena idea?

+0

¿Puede proporcionar una muestra de código, de los vectores dtor, y cómo se llama? –

+3

¿Qué hace _Tidy()? – Brian

+0

Muéstranos cómo se creó el vector. – sbi

Respuesta

1

Definitivamente no es una buena idea. Cualquier operación en un objeto después de que el destructor comience a funcionar produce un comportamiento indefinido.

+0

¿O más bien, después de que termine el destructor?Supongo que podría ser válido si construyes otra instancia en el mismo lugar con ubicación nueva antes de hacer cualquier otra cosa con la instancia y antes de que salga del alcance. – UncleBens

+0

Y estas operaciones incluyen el dtor que se invoca automáticamente al final del alcance. – sbi

+0

@UncleBens: no, tan pronto como se inicie el destructor debería considerar que su objeto ya no existe ... intente usar funciones virtuales de un destructor de una clase base que realmente use una memoria asignada en el montón de la clase derivada ... vea lo que quiero decir :) ? –

5

¿Podría esta clase usar algún tipo de método placement new? Esa es la única vez que tiendo a ver destructores explícitos en uso.

+0

Dame una paliza mientras escribía. ;) – John

1

Tal vez el codificador original se preocupó acerca de dónde en la memoria se asignaron los objetos.

A continuación, el destructor debe llamarse explícitamente, según this discussion.

+0

Cuál es probablemente el caso dado que la discusión trata sobre un vector asignado a la pila. –

5

¿Gran vector?

Supongo salvaje ... cuando se llama clear(), el vector generalmente se vacía pero la memoria no se libera. Es por eso que existe el patrón

std::vector<T>().swap(vector_to_clear); 

para vaciar el vector para reutilizar y borrar la memoria asignada.

Quizás el autor original no conocía el patrón y trató de deshacerse de la memoria asignada de esta manera perversa. (Creo que _Tidy libera la memoria asignada)

+0

Los vectores varían en tamaño pero ninguno eroneously grande. Me encantaría saber la intención original de los autores sobre esto, y con suerte fue solo una deslocalización de la memoria desasignación – Colin

+0

Mi primera pregunta es tales situaciones es: ¿Cuál es el comentario de verificación? – sbi

9

clear() no se garantiza que realmente libere el almacenamiento asignado en el vector; _Tidy() en la implementación de MSVC realmente liberará ese almacenamiento, por lo que probablemente se haya realizado como una optimización.

Es algo malo, pero puede hacerlo legalmente (sin un comportamiento indefinido) siempre que el almacenamiento sea reutilizado por un objeto del mismo tipo (ignorando cv-qualifiers) que ocupe exactamente todo el almacenamiento :

T automatic; 
automatic.T::~T(); 
new (&automatic) T(); 

La sección 3.8.7 de la norma C++ describe este escenario de uso y explica cómo es legal; incluso incluye un ejemplo que es similar al anterior.

Cuestiones relacionadas