2010-07-11 17 views
13

Si tengo una fábrica, que crea un objeto y devuelve un puntero a ella, lo que va a ser una mejor manera de eliminarlo:¿Dónde eliminar un objeto creado de fábrica?

Por delete llamada en el código "usuario", o mediante una nueva función DestructObject cuales Debería haberlo hecho junto con la fábrica?

+1

Depende de a quién pertenece el objeto una vez creado. Pero nunca es una buena idea devolver un puntero ya que no tiene semántica de propiedad asociada. –

Respuesta

13

En el caso general, la fábrica podría no usar el antiguo new para asignar el objeto. Puede usar la agrupación de objetos y/o páginas, malloc con la ubicación new, o algo aún más exótico (¿asignación de memoria?). Existen al menos tres maneras de manejar esto que se me ocurre:

  1. tiene un aporte de la fábrica un método recycle que se llamará cuando haya terminado con el objeto.
  2. Devuelve un puntero inteligente que sepa cómo deshacerse del objeto una vez que no queden referenciadores.
  3. Implemente un operador personalizado delete en el objeto mismo.

Vacilo en recomendar uno sobre el otro, ya que no he pensado lo suficiente en los últimos cinco minutos para ofrecer una opinión definitiva, pero tendería a preferir la última opción en combinación con un smart puntero como boost/tr1 :: shared_ptr.

+0

Tenga cuidado al pasar objetos por encima de los límites de DLL con shared_ptr. Use un intrusive_ptr luego ... Repasé ese problema una vez y eso destruyó mi esperanza de que al usar shared_ptr, siempre esté en el lado seguro. – jdehaan

+1

@jdehaan: shared_ptr invocará el 'delete' personalizado que siempre está en el" lado seguro ". –

+0

+1 para boost :: shared_ptr. Esa es la mejor manera de hacerlo. –

1

La mejor manera de eliminarlo manualmente sería not at all.

+2

El sarcasmo no se traduce bien a ningún formato grabado. Sería mejor aconsejar evitarlo y ser específico en lugar de ocultar el significado en los enlaces. Pero +1 para punteros inteligentes como un posible método. –

0

La solución más versátil para este problema es derivar su clase de una clase base que tiene una función virtual de "muerte". Algo como esto:

class IDisposable { 
public: 
    virtual void Release() = 0; 
}; 

Se cree generalmente que los objetos polimórficos deben tener destructores virtuales para apoyar la limpieza objeto propio. Sin embargo, esto es incompleto, porque no tiene en cuenta la administración de memoria potencialmente diferente de los objetos.

Por otro lado, este método no requiere el uso de destructores virtuales. Ahora es reemplazado por la función Release que hace ambos: invocación del destructor correcto y liberando la memoria por los medios apropiados.

se encarga del objeto dest

tanto: destrucción

El objeto devuelto por la fábrica va a poner en práctica esta "interfaz".

1

El siguiente código proporciona una oportunidad para no pensar en quién debería eliminar el objeto recién creado.

class FooFactory 
{ 
public: 
    static std::auto_ptr<Foo> CreateInstance(); 
}; 

// transmit ownership of created object from factory to 'a' variable 
std::auto_ptr<Foo> a = FooFactory::CreateInstance(); 
// using the created object is not required 
FooFactory::CreateInstance(); 
Cuestiones relacionadas