c++ memory-management c++11 move-semantics explicit-destructor-call

c++ - ¿Por qué es necesaria la llamada del destructor después del std:: move?



memory-management c++11 (1)

Moverse de un objeto simplemente significa que el objeto que se ha movido puede donar sus agallas para vivir en otro objeto vivo poco antes de que [probablemente] vaya a morir. Sin embargo, tenga en cuenta que solo porque un objeto haya donado sus agallas, ¡el objeto no está muerto! De hecho, puede ser revivido por otro objeto donante y vivir en las entrañas de ese objeto.

Además, es importante comprender que la construcción de movimientos o la asignación de movimientos pueden ser copias. De hecho, serán copias si el tipo que se mueve es un tipo anterior a C ++ 11 con un constructor de copia o una asignación de copia. Incluso si una clase tiene un constructor de movimiento o una asignación de movimiento, puede elegir que no pueda mover sus entrañas al nuevo objeto, por ejemplo, debido a la falta de coincidencia de los asignadores.

En cualquier caso, un objeto movido puede tener recursos o la necesidad de registrar estadísticas o lo que sea. Para deshacerse del objeto necesita ser destruido. Dependiendo de los contratos de la clase, incluso puede tener un estado definido después de ser trasladado y podría ser usado de nuevo sin ningún problema adicional.

En el lenguaje de programación C ++, edición 4, hay un ejemplo de una implementación vectorial, vea el código relevante al final del mensaje.

uninitialized_move () inicializa los nuevos objetos T en el área de memoria nueva moviéndolos desde el área de memoria antigua. Luego llama al destructor en el objeto T original, el objeto movido desde. ¿Por qué es necesaria la llamada destructor en este caso?

Aquí está mi comprensión incompleta: mover un objeto significa que la propiedad de los recursos que posee el objeto movido desde se transfiere al objeto movido a. Los restos en el objeto movido son algunos miembros posibles de los tipos incorporados que no necesitan ser destruidos, serán desasignados cuando la base de vectores b salga del ámbito (dentro de reserve () , después de la llamada swap () ). Todos los punteros en el objeto movido desde deben colocarse en nullptr o se emplea algún mecanismo para eliminar la propiedad del objeto movido desde esos recursos para que estemos a salvo, entonces, ¿por qué llamar al destructor en un objeto agotado cuando "vector_base b "¿el destructor desasignará la memoria después de que se realice el intercambio?

Entiendo la necesidad de llamar explícitamente al destructor en los casos en que se debe llamar porque tenemos algo que destruir (por ejemplo, eliminar elementos) pero no veo su significado después de std :: move + deallocation de vector_base. Leí algunos textos en la red y veo la llamada del destructor del objeto movido como una señal (¿a quién o qué?) Que la vida útil del objeto ha terminado.

¿Me aclaran qué trabajo significativo debe realizar el destructor? ¡Gracias!

El fragmento de código a continuación es de aquí http://www.stroustrup.com/4th_printing3.html

template<typename T, typename A> void vector<T,A>::reserve(size_type newalloc) { if (newalloc<=capacity()) return; // never decrease allocation vector_base<T,A> b {vb.alloc,size(),newalloc-size()}; // get new space uninitialized_move(vb.elem,vb.elem+size(),b.elem); // move elements swap(vb,b); // install new base } // implicitly release old space template<typename In, typename Out> Out uninitialized_move(In b, In e, Out oo) { using T = Value_type<Out>; // assume suitably defined type function (_tour4.iteratortraits_, _meta.type.traits_) for (; b!=e; ++b,++oo) { new(static_cast<void*>(&*oo)) T{move(*b)}; // move construct b->~T(); // destroy } return oo; }