Una nota interesante sobre los punteros inteligentes

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 .

Supongo que te gusta

Origin blog.csdn.net/qq_32783703/article/details/105262274
Recomendado
Clasificación