En la al contrario, siempre debe preferir las asignaciones de pila, en la medida en que, como regla general, nunca debe tener nuevo/eliminar en su código de usuario.
Como dices, cuando la variable se declara en la pila, se llama automáticamente a su destructor cuando se sale del alcance, que es tu herramienta principal para rastrear el tiempo de vida del recurso y evitar fugas.
Así que, en general, cada vez que se necesita para asignar un recurso, si se trata de la memoria (llamando nueva), identificadores de archivo, tomas de corriente o cualquier otra cosa, lo envuelve en una clase donde el constructor adquiere el recurso, y los comunicados de destructor eso. Luego puede crear un objeto de ese tipo en la pila, y se le garantiza que su recurso se liberará cuando salga del alcance. De esta manera, no tiene que seguir sus pares nuevos/eliminar en todas partes para asegurarse de evitar fugas de memoria.
El nombre más común para este idioma es RAII
también se ven en clases de punteros inteligentes que se utilizan para envolver los punteros resultantes en los raros casos en que usted tiene que asignar algo con nuevo fuera de un objeto RAII dedicado. En su lugar, pasa el puntero a un puntero inteligente, que luego rastrea su duración, por ejemplo, mediante recuento de referencias, y llama al destructor cuando la última referencia sale del alcance.La biblioteca estándar tiene std::unique_ptr
para la administración simple basada en el alcance y std::shared_ptr
que hace referencia al recuento para implementar la propiedad compartida.
Muchos tutoriales demuestran objeto de instancias utilizando un fragmento como ...
Así que lo que he descubierto es que la mayoría de los tutoriales son los peores. ;) La mayoría de los tutoriales le enseñan prácticas pésimas de C++, incluida la invocación de nuevas/eliminar para crear variables cuando no es necesario, y le dificultan el seguimiento de la vida de sus asignaciones.
Los punteros sin formato son útiles cuando se quiere una semántica parecida a auto_ptr (transferencia de propiedad), pero se conserva la operación de intercambio sin lanzamiento y no se desea la sobrecarga del recuento de referencias. Edge case tal vez, pero útil. –
Esta es una respuesta correcta, pero la razón por la que nunca tendría el hábito de crear objetos en la pila es porque nunca es completamente obvio qué tan grande será ese objeto. Solo está pidiendo una excepción de desbordamiento de pila. – dviljoen
Greg: Ciertamente. Pero como dices, un caso extremo. En general, es mejor evitar punteros. Pero están en el idioma por una razón, sin negar eso. :) dviljoen: Si el objeto es grande, lo envuelve en un objeto RAII, que puede asignarse en la pila y contiene un puntero a los datos asignados al montón. – jalf