weak_ptr smart shared_ptr pointer example create c++ c++11 shared-ptr smart-pointers

c++ - smart - std:: initialización shared_ptr: make_shared<Foo>() vs shared_ptr<T>(nuevo Foo)



smart pointers c++ (3)

Ambos ejemplos son bastante más detallados de lo necesario:

std::shared_ptr<int> p(new int); // or ''=shared_ptr<int>(new int)'' if you insist auto p = std::make_shared<int>(); // or ''std::shared_ptr<int> p'' if you insist

¿Cual es la diferencia?

La principal diferencia es que la primera requiere dos asignaciones de memoria: una para el objeto gestionado ( new int ) y otra para el recuento de referencias. make_shared debe asignar un solo bloque de memoria y crear ambos en eso.

¿Cuál debería preferir y por qué?

Por lo general, debes usar make_shared ya que es más eficiente. Como se señala en otra respuesta, también evita cualquier posibilidad de pérdida de memoria, ya que nunca tiene un puntero sin formato al objeto administrado.

Sin embargo, como se señala en los comentarios, tiene la desventaja potencial de que la memoria no se liberará cuando se destruya el objeto, si todavía hay punteros débiles que impiden que se borre el recuento compartido.

Esta pregunta ya tiene una respuesta aquí:

Cuál es la diferencia entre:

std::shared_ptr<int> p = std::shared_ptr<int>( new int );

y

std::shared_ptr<int> p = std::make_shared< int >();

?

¿Cuál debería preferir y por qué?

PD: Bastante seguro de que esto ya debe haber sido respondido, pero no puedo encontrar una pregunta similar.


De en.cppreference.com

Por el contrario, la declaración std::shared_ptr<T> p(new T(Args...)) realiza al menos dos asignaciones de memoria, lo que puede generar una sobrecarga innecesaria.

Además, f(shared_ptr<int>(new int(42)), g()) puede provocar pérdida de memoria si g arroja una excepción. Este problema no existe si se usa make_shared.

Así que recomendaría el método make_shared si es posible.


Tenga en cuenta que make_shared limita a utilizar las funciones predeterminadas de asignación / desasignación, por lo que si desea tener más control, make_shared no es una opción. En otras palabras, algo como

std::shared_ptr<uint8_t>(p, [](uint8_t *p){ /*user code */});

es imposible usando make_shared . Uno podría usar allocate_shared lugar, pero solo se puede especificar el asignador, no un eliminador. Algunas veces es necesario controlar la asignación y eliminación de la clase envuelta.