¿Tiene que pasar eliminar el mismo puntero que fue devuelto por nuevo, o puede pasarlo un puntero a uno de los tipos básicos de clases? Por ejemplo:¿Eliminar trabajo con punteros a la clase base?
class Base
{
public:
virtual ~Base();
...
};
class IFoo
{
public:
virtual ~IFoo() {}
virtual void DoSomething() = 0;
};
class Bar : public Base, public IFoo
{
public:
virtual ~Bar();
void DoSomething();
...
};
Bar * pBar = new Bar;
IFoo * pFoo = pBar;
delete pFoo;
Por supuesto, esto se simplifica enormemente. Lo que realmente quiero hacer es crear un contenedor lleno de boost :: shared_ptr y pasarlo a algún código que lo elimine del contenedor cuando esté terminado. Este código no sabrá nada de la implementación de Bar o Base, y se basará en el operador de eliminación implícita en el destructor shared_ptr para hacer lo correcto.
¿Es posible que esto funcione? Mi intuición dice que no, ya que los punteros no tendrán la misma dirección. Por otro lado, un dynamic_cast < Bar *> debería funcionar, por lo que en algún lugar el compilador está almacenando suficiente información para resolverlo.
Gracias por la ayuda, todos los que respondieron y comentaron. Ya sabía la importancia de los destructores virtuales, como se muestra en mi ejemplo; después de ver la respuesta, lo pensé un poco, y me di cuenta de que el motivo completo para un destructor virtual es este escenario exacto. Por lo tanto, tenía que funcionar. Me sorprendió la ausencia de un medio visible de convertir el puntero al original. Un poco más de pensamiento me llevó a creer que había un medio invisible, y teoricé que el destructor estaba devolviendo el verdadero puntero para que delete se liberara. Investigando el código compilado de Microsoft VC++ confirmó mi sospecha cuando vi esta línea de la base de ~:
mov eax, DWORD PTR _this$[ebp]
Tracing el ensamblador reveló que este era el puntero se pasa a la función de borrado. Misterio resuelto.
He arreglado el ejemplo para agregar el destructor virtual a IFoo, fue un simple descuido. Gracias de nuevo a todos los que lo señalaron.
Sé la importancia de un destructor virtual para destruir el objeto correctamente, por eso lo incluí en el ejemplo; ¿Estás diciendo que también hará que se libere la memoria adecuada? Y también necesito un destructor virtual para IFoo? –
En realidad, está bien eliminar cualquier referencia siempre que la clase más básica tenga un destructor virtual. Una vez que un destructor sea virtual, todas las implementaciones derivadas tendrán un destructor virtual, esté o no especificado. C++ es divertido. – JaredPar
La memoria real probablemente se liberará incluso sin el destructor virtual. – Eclipse