2010-07-12 15 views
5

Tengo dos clases con una relación padre-hijo (cliente & fin directorio de archivos & etc)impulso shared_ptr y 'esto'

tengo

typedef boost::shared_ptr<Parent> ParentPtr 

y en la clase padre de un método para hacer una hijo

Necesito instancias hijo para tener punteros a su padre.

class Child 
{ 
.... 
    ParentPtr m_parent; 
.... 
} 

Quiero que sea un shared_ptr para que el padre no desaparece, mientras que hay niños existentes. También tengo otras personas que tienen ParentPtrs al padre (el método de fábrica para los padres devuelve un ParentPtr)

Pregunta: ¿cómo se puede dar al niño un intento ParentPtr

(1). En Padres :: ChildFactory

child->m_parent.reset(this); 

esto se traduce en cosas muy malas. Ahora hay 2 ParentPtr 'cadenas' apuntando al padre; el resultado es la muerte prematura de la matriz

intento (2). El padre tiene

ParentPtr m_me; 

que se copia del valor de retorno de la fábrica principal. Por lo que puedo hacer

child->m_parent = m_me; 

Pero ahora los padres nunca muere, ya que contiene una referencia a sí mismo

Respuesta

8

Estoy bastante seguro de que enable_shared_from_this resuelve su problema: http://live.boost.org/doc/libs/1_43_0/libs/smart_ptr/enable_shared_from_this.html

Si derivó su clase a partir de una especialización de boost::enable_shared_from_this luego puede usar shared_from_this() en una función de miembro para obtener el puntero compartido que posee this (suponiendo que haya uno).

E.g.

class Parent : public boost::enable_shared_from_this<Parent> 
{ 
    void MakeParentOf(Child& c) 
    { 
     c.m_parent = shared_from_this(); 
    } 
}; 
+0

excelentes respuestas - gracias – pm100

+0

@ pm100: ¿Por qué necesita usar un 'weak_ptr'? Si los niños son dueños de sus padres (los comparten entre ellos), entonces necesitas usar 'shared_ptr'. Un 'weak_ptr' no implica propiedad. –

+0

oh sí, estás en lo correcto - estaba pensando en una solución diferente - eliminando edit – pm100

0

Como la otra respuesta tiene puntero, en primer lugar se tendrá que usar la enable_shared_from_this para obtener el shared_ptr, pero entonces el niño no puede sostener que ref, se debe utilizar un weak_ptr. Un weak_ptr es como un shared_ptr excepto que no mantendrá una referencia hasta que llame al método get(), que le devolverá un shared_ptr normal que debe deshacerse tan pronto como pueda dentro del niño.

+0

¿Por qué crees esto?El modelo es que los niños (junto con "otras personas") son dueños de sus padres; los padres no son dueños de los niños. Si los niños usan un puntero débil, no impedirá que los padres "desaparezcan" mientras todavía tengan hijos. –

+0

@Charles Lo siento, mi mal. Estoy asumiendo cosas que no se mencionaron explícitamente: asumí que si se usaban 'shared_ptr' y' weak_ptr', los padres tendrían referencias a sus hijos. Supuse que, simplemente porque, de forma predeterminada, los padres controlan a sus hijos, hasta que al menos cumplen 18 años y se van de casa. Si es al revés, ignora todo lo que dije. – Gianni

+0

Bueno, no sé exactamente cuál es la estructura del código de PM100, pero estaba pensando que si le preocupa que los padres sean destruidos mientras todavía tenían hijos, entonces la clase de padres no podría poseer (ya sea directamente por valor o por medio de un 'shared_ptr') las clases secundarias, de lo contrario ni siquiera sería una consideración. La relación de propiedad aseguraría que un niño no pueda sobrevivir a su último padre. Tal como está, entiendo que la propiedad requerida es al revés: "Quiero que sea un shared_ptr para que el padre no desaparezca mientras haya hijos". –

Cuestiones relacionadas