c++ - punteros - tipos de cursores y su funcion
¿Cuál es la diferencia entre el puntero en bruto y weak_ptr? (2)
Un puntero en bruto es (al menos normalmente) simplemente una dirección. No se puede decir nada sobre lo que apunta desde el puntero en sí.
Un weak_ptr
siempre se asocia con shared_ptr
, por lo que probablemente necesitamos comenzar con shared_ptr
para dar sentido a un valor weak_ptr
.
Un shared_ptr
es una referencia contada, por lo que realiza un seguimiento de cuántas referencias (punteros) existen a un objeto, y destruye automáticamente el objeto cuando no existen más referencias a ese objeto.
Como ya dije, un weak_ptr
está asociado con shared_ptr
. A diferencia de shared_ptr
, la existencia de weak_ptr
no incrementa el recuento de referencia para el objeto pointee. Para utilizar un valor weak_ptr
, primero debe convertirlo en un valor shared_ptr
. Si el recuento de referencia actual es positivo, tendrá éxito, y la conversión de weak_ptr
a shared_ptr
incrementará el recuento de referencia para indicar que el puntero convertido es una referencia "real" al objeto. Si, por otro lado, el recuento de referencia ya es cero (lo que significa que el objeto puntual ya se ha destruido), el intento de convertir un shared_ptr
weak_ptr
en un valor shared_ptr
será simplemente fallido.
Una shared_ptr
significa propiedad compartida del objeto pointee. El objeto pointee seguirá existiendo mientras exista al menos un shared_ptr para ese objeto, pero tan pronto como se shared_ptr
el último shared_ptr
para el objeto, también lo hará el objeto pointee.
Un valor weak_ptr
significa acceso no propietario al objeto pointee. Permite el acceso si el objeto existe. Si el objeto ha sido destruido, le indica que el objeto puntual ya no existe en lugar de intentar acceder al objeto destruido.
Como en el título. Esta pregunta probablemente ya tiene una respuesta pero no pude encontrarla.
La diferencia conceptual fundamental entre un puntero desnudo y un weak_ptr
es que si el objeto al que se apunta se destruye, el puntero desnudo no te lo dirá. Esto se denomina puntero colgante: un puntero a un objeto que no existe. En general, son difíciles de rastrear.
El weak_ptr
hará. Para utilizar un valor weak_ptr
, primero debe convertirlo en un valor shared_ptr
. Y si el shared_ptr
no apunta a nada, entonces el objeto fue eliminado.
Por ejemplo:
#include <iostream>
#include <memory>
std::weak_ptr<int> wp;
void test()
{
auto spt = wp.lock(); // Has to be copied into a shared_ptr before usage
if (spt) {
std::cout << *spt << "/n";
} else {
std::cout << "wp is expired/n";
}
}
int main()
{
{
auto sp = std::make_shared<int>(42);
wp = sp;
test();
}
test();
}
Salida
42
wp is expired