No, no es seguro. foo
y bar
necesitan destructores virtuales, de lo contrario no está definido lo que sucede cuando el destructor de shared_ptr
borra el puntero que contiene. Por supuesto, decir que no es seguro no es lo mismo que decir que debería colapsar.
Como alternativa, hay un poco de magia [*] integrado en shared_ptr
lo que significa que si no desechan a foo*
, su código se convierte en segura:
fooptr f(fb1);
barptr b(fb2);
ya sea con el destructor virtual, o si usted toma los moldes, cuando shared_ptr viene a eliminar el puntero, el compilador "sabrá" cómo ajustar el puntero a su tipo original, para llamar a los destructores correctos y liberar la memoria.
La magia solo funciona porque fb1
es tipo foobar*
, sin embargo. Sin el destructor virtual, lo que sigue es todavía inseguro:
foo *fb = new foobar();
fooptr f(fb);
Si utiliza shared_ptr
así, entonces no hay riesgo de hacer lo siguiente:
fooptr f(new foobar());
También puede evitar el problema de que en su código , que si la segunda llamada al new foobar()
arroja una excepción, se filtra el primer objeto. Si usted va a utilizar shared_ptr
a gestionar la memoria para usted, entonces usted necesita para obtener la memoria bajo la gestión lo más rápidamente posible:
fooptr f(new foobar());
barptr b(new foobar());
Ahora bien, si la segunda línea lanza, f
será adecuadamente destructed y borrará el objeto.
[*] "magic" = una plantilla de constructor, que almacena en el shared_ptr
un puntero a una función que devolverá el puntero almacenado al tipo correcto y luego lo eliminará.
+1, me ganaste para explicar el constructor de la plantilla. –
gracias por su respuesta :) – ddh