lo que todas las respuestas dadas hasta ahora se reducen a lo siguiente: evitar tener que llamar al.
Cada vez que el programador tiene que llamar al delete
, tiene una posible pérdida de memoria. En su lugar, haga que la llamada delete
suceda automáticamente. C++ garantiza que los objetos locales tienen sus destructores llamados cuando salen del alcance. Use esa garantía para asegurarse de que las asignaciones de memoria se eliminen automáticamente.
En su forma más general, esta técnica significa que cada asignación de memoria debe envolverse dentro de una clase simple, cuyo constructor asigna la memoria necesaria, y destructor la libera.
Debido a que esta es una técnica muy utilizada y ampliamente aplicable, se han creado clases de punteros inteligentes que reducen la cantidad de código repetitivo. En lugar de asignar memoria, sus constructores toman un puntero a la asignación de memoria ya realizada, y lo almacena. Cuando el puntero inteligente se sale del alcance, puede eliminar la asignación.
Por supuesto, dependiendo del uso, puede ser necesaria una semántica diferente. ¿Simplemente necesita el caso simple, donde la asignación debería durar exactamente mientras dure la clase contenedora? Luego use boost::scoped_ptr
o, si no puede usar boost, std::auto_ptr
. ¿Tiene un número desconocido de objetos que hacen referencia a la asignación sin conocimiento de cuánto tiempo vivirá cada uno de ellos? Entonces el boost::shared_ptr
contado por referencia es una buena solución.
Pero no tiene que utilizar punteros inteligentes. Los contenedores de biblioteca estándar también funcionan. Asignan internamente la memoria necesaria para almacenar copias de los objetos que colocas en ellas, y vuelven a liberar la memoria cuando se eliminan. Por lo tanto, el usuario no tiene que llamar al new
o al delete
.
Existen innumerables variaciones de esta técnica, cambiando la responsabilidad de crear la asignación de memoria inicial, o cuando se debe realizar la desasignación.
Pero lo que todos tienen en común es la respuesta a su pregunta: RAII idioma: Adquisición de recursos es inicialización. Las asignaciones de memoria son un tipo de recurso. Los recursos deben ser adquiridos cuando un objeto es inicializado y liberado por el objeto itslef, cuando es destruido.
Haga que el alcance de C++ y las reglas de por vida hagan su trabajo por usted.Nunca llame al delete
fuera de un objeto RAII, ya sea una clase de contenedor, un puntero inteligente o algún contenedor ad-hoc para una sola asignación. Deje que el objeto maneje el recurso asignado a él.
Si todas las llamadas delete
se realizan automáticamente, no hay forma de que las pueda olvidar. Y entonces no hay forma de que puedas perder memoria.
Usa un recolector de basura (http://www.google.com/search?q=Garbage+collection+c%2B%2B) ...? – kennytm
@KennyTM No, no use un recolector de basura, cuando tenga RAII. Si realmente necesita propiedad compartida, solo use shared_ptr desde C++ 0x o boost actualmente. – AraK
@Kenny: si quieres vivir con los problemas asociados con GC. C++ tiene un mecanismo de control mucho mejor definido llamado punteros inteligentes. –