c++ - ¿Cómo se inicializa un std::unique_ptr a una referencia?

CorePress2024-01-24  13

Con punteros sin formato puedo hacer:

int x = 10;
int* y = &x;

x = 20;
std::cout << *y; //prints 20

Sin embargo, estoy luchando por emular el mismo comportamiento con std::unique_ptr. Lo he probado:

int x = 10;

std::unique_ptr<int> y = std::make_unique(&x); //doesnt compile
std::unique_ptr<int> y = std::make_unique<int>(&x); //doesnt compile
std::unique_ptr<int&> y = std::make_unique(x); //doesnt compile
std::unique_ptr<int> y = std::make_unique<int&>(&x); //doesnt compile

std::unique_ptr<int> y = std::make_unique<int>(x); //compiles but prints y = 10, which is not the desired behaviour

Estoy seguro de que hay una manera, por lo que se agradece cualquier ayuda. Gracias.

@RemyLebeau Eso tiene sentido, toda esta charla sobre no usar punteros sin formato me ha afectado. encogimiento de hombros. Gracias :)

- jf192210

27 de marzo de 2021 a las 0:17

1

No hay nada malo en utilizar punteros sin formato en general, siempre y cuando no se utilicen para tratar con la semántica de propiedad. Lo que ya no se recomienda es usar nuevo/eliminar directamente, en lugar de contenedores estándar y punteros inteligentes que brindan una semántica de propiedad más sólida. Dos cosas diferentes.

- Rémy Lebeau

27 de marzo de 2021 a las 0:17

1

Tenga en cuenta que si programa en C++ mediante prueba y error,lo vas a pasar mal. Undefined Behavior acecha en la oscuridad, esperando abalanzarse sobre el programador desprevenido. La documentación es tu amiga.

- alter_igel

27 de marzo de 2021 a las 0:24

@alterigel Estaba leyendo la referencia de cpp, pero me estaba volviendo loco porque no mostraba cómo inicializar un ptr único a partir de una referencia. doh... no puedes hacer eso, así que no está en la referencia de cpp. Debería haber leído el texto pequeño.

- jf192210

27 de marzo de 2021 a las 0:26



------------------------------------

unique_ptr trata sobre la gestión de la vida útil de la memoria asignada dinámicamente.

Es decir

std::unique_ptr<int> y = std::make_unique<int>(x);

dice asignar memoria para un número entero, copiar el valor de x en él y cuando y salga del alcance, libere esa memoria.

En su ejemplo, no está interesado en administrar la vida útil del almacenamiento asignado, solo desea otra "vista" de lo que está almacenado para x. No es para lo que está diseñado Unique_ptr.



------------------------------------

No hay asignación dinámica en el primer código, por lo que no es necesario try para emularlo con Unique_ptr.

unique_ptr administra un puntero a un objeto asignado con new y eliminará ese objeto cuando Unique_ptr salga del alcance. No puedes hacer que Unique_ptr actúe como referencia a un objeto externo que no le pertenece.

Dicho esto, si desea que dos punteros inteligentes hagan referencia al mismo objeto en la memoria, utilice share_ptr en lugar de Unique_ptr, por ejemplo:

#include <memory>

auto x = std::make_shared<int>(10);
auto y = x;

*x = 20;
std::cout << *y; //prints 20

Demostración

2

Puedes tener el ptr único "administrar" la dirección y darle una eliminación noopejem. No tiene sentido, pero hace lo que pide OP

-AndyG

27 de marzo de 2021 a las 0:31

@AndyG en esa situación, en realidad no es mejor que un std::reference_wrapper.

- Rémy Lebeau

27 de marzo de 2021 a las 0:49

Su guía para un futuro mejor - libreflare
Su guía para un futuro mejor - libreflare