En los últimos días, tengo más curiosidad sobre si el puntero inteligente de C ++ se destruirá después de dejar el alcance La duda proviene de un pequeño código escrito por mí.
int count = 0;
vector<weak_ptr<Observer>> observers;
typedef std::vector<weak_ptr<Observer>>::iterator Iterator;
while (1) {
shared_ptr<Foo> p(new Foo);
weak_ptr<Foo> w(p);
observers.push_back(w);
Iterator it = observers.begin();
while(it != observers.end())
{
cout<<w.lock()<<endl;
it++;
}
if(count == sum)
{
break;
}
}
En este fragmento de código, tendré mucha curiosidad por encontrar que el puntero inteligente p se cuelga después de la primera llamada, porque el puntero débil_ptr puede determinar si un objeto está vivo. Por supuesto, no crea que frecuentemente hago make_shared en la pila. El puntero cambiará. Si aplica en la pila, ¡siempre será la dirección de memoria! Luego fui a verificar la información y escribí el siguiente código
int main()
{
// pthread_t thread1;
// pthread_t thread2;
// pthread_t thread3;
// pthread_create(&thread1, nullptr,threadOne,nullptr);
// pthread_create(&thread2,nullptr,threadTwo,nullptr);
// pthread_create(&thread3,nullptr,threadThree,nullptr);
//
// pthread_join(thread1,nullptr);
// pthread_join(thread2,nullptr);
// pthread_join(thread3,nullptr);
weak_ptr<Foo> globalPtr;
{
auto p = make_shared<Foo>();
weak_ptr<Foo> p2(p);
globalPtr = p2;
cout<<globalPtr.lock()<<endl;
}
cout<<globalPtr.lock()<<endl;
}
Este código es en realidad más interesante. Después de salir del alcance, globalptr se destruye y el resultado se
0x5628df8eae80
0
De hecho, después de que el puntero inteligente se sale del alcance, activará el proceso de destrucción y reducirá el contador. Si el contador es 0, el puntero inteligente se destruirá de forma natural, porque débil_ptr no puede aumentar el contador (referencia débil) de shared_ptr. En este momento, después de salir del alcance, el contador de p es 0, que se destruye en este momento, y el globalptr se destruye naturalmente, por lo que aparecerá 0. Por supuesto, si reemplazamos globalptr con débilptr, no hay problema .