Los destructores de clase no se les llama en el orden inverso esperado de donde se inicializaron en -- ++ campo con smart-pointers camp Relacionados El problema

Class Destructors not being called in the expected reverse order from which they were initialized in


0
vote

problema

Español

Estaba probando los punteros inteligentes y cómo funcionan y me encontré con un "problema". Aquí está el código del cual hablaré:

  #include <iostream> #include <memory>  class B; // forward declaration  class A {  private:     std::shared_ptr<B> b_ptr;  public:     void set_B(std::shared_ptr<B> &b) {          b_ptr = b;         std::cout << b_ptr.use_count() << std::endl;     }      A() { std::cout << "A Constructor" << std::endl; }     ~A() { std::cout << "A Destructor" << std::endl; }  };  class B {  private:     std::weak_ptr<A> a_ptr;  public:     void set_A(std::shared_ptr<A> &a) {          a_ptr = a;         std::cout << a_ptr.use_count() << std::endl;     }      B() { std::cout << "B Constructor" << std::endl; }     ~B() { std::cout << "B Destructor" << std::endl; }  };  int main() {      std::shared_ptr<A> a{std::make_shared<A>()};     std::shared_ptr<B> b{std::make_shared<B>()};      a->set_B(b);     b->set_A(a);      return 0;  }   

y aquí está la salida cuando corrió:

  A Constructor B Constructor 2 1 A Destructor B Destructor   

Ahora, mi pregunta es, ¿por qué los destructores no se llaman en orden inverso desde cuándo se inicializan, p.g ( esto es lo que esperaba para que la producción sea ):

  A Constructor B Constructor 2 1 B Destructor A Destructor   

La salida anterior es lo que esperaba, pero ese no fue el caso. Lo que pude crear fue lo siguiente:

  • variable b sale de alcance (como se espera)
  • Pero tiene dos referencias fuertes, por lo que el objeto asignado dinámicamente que b estaba apuntando a no se destruye aún el objeto b mismo como un std::shared_ptr6 El objeto se destruye y de modo que deja solo 1 referencia sólida en ese objeto tipo std::shared_ptr77
  • La variable a sale de alcance siguiendo los eventos anteriores, y a su vez, tiene solo 1 referencia sólida debido al std::weak_ptr que no afecta a A Constructor B Constructor 2 1 A Destructor B Destructor 0 's Lifetime / Uso_Count, lo que significa que el objeto tipo std::shared_ptr611111 (código> std::shared_ptr61111 "dinámicamente asignado ... pero ahí es donde me pregunto cómo se llama el destructor B después de la una que solo hace 'T Tengo algún sentido para mí
Original en ingles

I was testing out smart pointers and how they work and I ran into an "issue". Here is the code which I will be talking about:

#include <iostream> #include <memory>  class B; // forward declaration  class A {  private:     std::shared_ptr<B> b_ptr;  public:     void set_B(std::shared_ptr<B> &b) {          b_ptr = b;         std::cout << b_ptr.use_count() << std::endl;     }      A() { std::cout << "A Constructor" << std::endl; }     ~A() { std::cout << "A Destructor" << std::endl; }  };  class B {  private:     std::weak_ptr<A> a_ptr;  public:     void set_A(std::shared_ptr<A> &a) {          a_ptr = a;         std::cout << a_ptr.use_count() << std::endl;     }      B() { std::cout << "B Constructor" << std::endl; }     ~B() { std::cout << "B Destructor" << std::endl; }  };  int main() {      std::shared_ptr<A> a{std::make_shared<A>()};     std::shared_ptr<B> b{std::make_shared<B>()};      a->set_B(b);     b->set_A(a);      return 0;  } 

And here is the output when ran:

A Constructor B Constructor 2 1 A Destructor B Destructor 

Now my question is why are the destructors not being called in reverse order from when they are initialized in, e.g (this is what I expected for the output to be):

A Constructor B Constructor 2 1 B Destructor A Destructor 

The above output is what I was expecting but that wasn't the case. What I could come up with was the following:

  • variable b goes out of scope (as expected)
  • but it has two strong references so the dynamically allocated object which b was pointing to is not destroyed yet the object b itself as a std::shared_ptr object is destroyed and so that leaves only 1 strong reference on that dynamically allocated B type object
  • the variable a goes out of scope following the events above, and it in-turn has only 1 strong reference due to the std::weak_ptr not affecting a std::share_ptr's lifetime/use_count, that means that the dynamically allocated A type object is destructed... but that is where I wonder how the B destructor gets called after the A one it just doesn't make any sense to me
     
       
       

Lista de respuestas

0
 
vote
vote
La mejor respuesta
 

a posee una referencia a b.

Su main El alcance posee una referencia a A y <li></li>0 . Cuando <li></li>111111 Finaliza la referencia <li></li>2 , luego el <li></li>3 .

El <li></li>4 DROUNTS El recuento de referencia a 1. El <li></li>5 A 0. 99887776616 S Destructor Luego se ejecuta.

Después de que el cuerpo del destructor se ejecute, cada miembro es destruido. <li></li>7 S Referencia a <li></li>8 desaparece. <li></li>9 S Destructor se llama.

por lo tanto el orden que ve.

 

A owns a reference to B.

Your main scope owns a reference to A and B. When main ends it drops the B reference, then the A.

The B reference drops the reference count to 1. The A to 0. As destructor then runs.

After the body of the destructor runs, each member is destroyed. As reference to B goes away. Bs destructor is called.

Thus the order you see.

 
 

Relacionados problema

2  C ++ Equivalentemente versión activa de la implementación similar a C  ( C equivalently performant version of c like implementation ) 
Estoy aprendiendo C ++ mientras me encuentro con esta situación, donde quiero implementar una versión equivalente eficiente en C ++ del siguiente código simbó...

3  Argumento de la función de doble puntero y CCOMPTR  ( Double pointer function argument and ccomptr ) 
No estoy seguro de esta forma de usar CCOMPTR dentro de una función que tiene un argumento expresado como un puntero doble: HRESULT D3DPresentEngine::Creat...

0  Convertir un puntero crudo a un clone_ptr  ( Convert a raw pointer to a clone ptr ) 
Tengo una implementación de clone_ptr, como se mostró en esta pregunta y tengo un problema en el que necesito crear un clone_ptr de un puntero crudo devuelt...

105  ¿Dónde está Shared_PTR?  ( Where is shared ptr ) 
Estoy tan frustrado en este momento después de varias horas tratando de encontrar dónde se encuentra Shared_PTR. Ninguno de los ejemplos Veo Mostrar código co...

5  ¿Hay un caso de uso para STD :: Unique_PTR <STD :: Array <T, N >>  ( Is there a use case for stdunique ptrstdarrayt n ) 
Me encontré con algo como: using arr_t=std::array<std::array<std::array<int,1000>,1000>,1000>; std::unique_ptr<arr_t> u_ptr; Obviamente se usó el punte...

110  ¿Cuánto cuesta la sobrecarga de los punteros inteligentes en comparación con los punteros normales en C ++?  ( How much is the overhead of smart pointers compared to normal pointers in c ) 
¿Cuánto cuesta la sobrecarga de los punteros inteligentes en comparación con los punteros normales en C ++ 11? En otras palabras, ¿mi código va a ser más lent...

2  Montando un STD :: shared_ptr causa segfault  ( Upcasting a stdshared ptr causes segfault ) 
Esta es una simplificación excesiva, pero no puedo recrear el problema. onCreate()0 La verificación estática no encuentra errores y este programa se eje...

1  Crea un objeto solo si alguna condición, de lo contrario, devuelve NULLPTR  ( Create object only if some condition otherwise return nullptr ) 
Quiero crear un objeto solo si se aplican algunas condiciones, de lo contrario, retun. Así es como lo haría en Delphi (2009 +): $this->value7 Así es com...

1  problema clone_ptr, necesito crear un objeto de copia usando una función de la biblioteca en lugar de nuevo  ( Clone ptr problem i need to create a copy object using a function of the librar ) 
Soy un poco nuevo en plantillas en C ++, así que perdóname si esta pregunta es confusa o estúpida, solo tengo un problema en el que quiero implementar un punt...

1  C ++ y punteros inteligentes: ¿cómo ayudarían los indicadores inteligentes en esta situación?  ( C and smart pointers how would smart pointers help in this situation ) 
Mucho a mi vergüenza, no he tenido la oportunidad de usar los punteros inteligentes en el desarrollo real (el Supervisor lo considera demasiado "complejo" y u...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos