¿Cómo inicializar un rpp compartido que es miembro de una clase?


No estoy seguro de una buena manera de inicializar un shared_ptr que es miembro de una clase. ¿Puedes decirme si el camino que elijo en C::foo() está bien, o hay una solución mejor?

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);
}
Author: Igor Oks, 2010-08-23

1 answers

Su código es bastante correcto (funciona), pero puede usar la lista de inicialización, así:{[19]]}

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

Que es aún más correcto y seguro.

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

Si new A lanza, entonces no se asigna memoria, y la excepción aborta su constructor también. No se construyó nada.

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

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

El orden de la declaración de miembro es correcto en su ejemplo, pero si se invirtiera, entonces su compilador probablemente se quejaría de mB estar inicializado antes de mA y la instanciación de mB probablemente fallaría (ya que mA no se construiría todavía, por lo tanto llamando a mA.get() invoca indefinido comportamiento).


También sugeriría que uses un shared_ptr<A> en lugar de un A* como parámetro para tu constructor B ( si tiene sentido y si puedes aceptar la pequeña 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 contexto aquí para dar un consejo definitivo sobre esto.

 30
Author: ereOn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-23 08:57:00