std:: inicialización del rpp compartido: make shared () vs shared ptr (nuevo Foo) [duplicar]


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é?

P. S. Bastante seguro de que esto ya debe haber sido contestado, pero no puedo encontrar una pregunta similar.

Author: CashCow, 2013-08-18

3 answers

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

¿Cuál es la diferencia?

La principal diferencia es que la primera requiere dos asignaciones de memoria: una para el objeto administrado (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é?

Normalmente deberías usar make_shared ya que es más eficiente. Como se señaló en otra respuesta, también evita cualquier posibilidad de una fuga de memoria, ya que nunca tiene un puntero raw al objeto administrado.

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

 47
Author: Mike Seymour,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-02 16:26:45

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, que pueden incurrir en sobrecarga innecesaria.

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

Así que recomendaría el enfoque make_shared si es posible.

 13
Author: Adri C.S.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-28 19:31:49

Tenga en cuenta que make_shared lo limita a usar las funciones de asignación/desasignación predeterminadas, 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 usar make_shared. Se podría usar allocate_shared en su lugar, pero solo se puede especificar el asignador, no un deleter. A veces es necesario controlar la asignación y eliminación de la clase empaquetada.

 9
Author: doc_ds,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-22 10:44:22