2010-08-23 21 views
34

No estoy seguro acerca de una buena forma de inicializar un shared_ptr que es miembro de una clase. ¿Puede decirme si la forma que elijo en C::foo() está bien o hay una mejor solución?¿Cómo inicializar un shared_ptr que es miembro de una clase?

class A 
{ 
    public: 
    A(); 
}; 

class B 
{ 
    public: 
    B(A* pa); 
}; 

class C 
{ 
    boost::shared_ptr<A> mA; 
    boost::shared_ptr<B> mB; 
    void foo(); 
}; 

void C::foo() 
{ 
    A* pa = new A; 
    mA = boost::shared_ptr<A>(pa); 
    B* pB = new B(pa); 
    mB = boost::shared_ptr<B>(pb); 
} 
+2

Use las listas de inicialización. – Chubsdad

+0

chubsdad: no funcionará en miembros, solo en ctors. – MSalters

+0

@MSalters: no tengo idea de lo que intentas decir. – sbi

Respuesta

30

Su código es bastante correcto (funciona), pero se puede utilizar la lista de inicialización, como esto:

C::C() : 
    mA(new A), 
    mB(new B(mA.get()) 
{ 
} 

que es aún más correcto y lo más seguro.

Si, por alguna razón, new A o new B lanza, no tendrá ninguna fuga.

Si new A arroja, entonces no se asigna memoria, y la excepción anula también su constructor. Nada fue construido.

Si new B arroja, y la excepción aún abortará su constructor: mA se destruirá correctamente.

Por supuesto, como una instancia de B requiere un puntero a una instancia de A, el orden de la declaración de los miembros importa.

El orden de declaración de miembro es correcta en su ejemplo, pero si se invierte, entonces el compilador probablemente se queja de mB beeing inicializado antes mA y la creación de instancias de mB es probable que falle (ya mA no se construiría sin embargo, por lo tanto llamando al mA.get() invoca un comportamiento indefinido).


También sugeriría que utilice un shared_ptr<A> en lugar de un A* como un parámetro para su B constructor (si se hace sentidos y si se puede aceptar la poca sobrecarga). Probablemente sería más seguro.

Tal vez se garantice que una instancia de B no puede vivir sin una instancia de A y entonces mi consejo no se aplica, pero nos falta de contexto aquí para dar un consejo definitivo al respecto.

+1

Dado que confía en él, vale la pena hablar sobre cómo funciona el orden de construcción de los miembros y los puntos de secuencia involucrados. –

+0

@ereOn: ¿un tipo de devolución para un constructor? – DumbCoder

+0

@DumbCoder: copiado de la pregunta donde también está mal. Lo arreglé. – sbi

Cuestiones relacionadas