2012-01-12 14 views
15

no puedo pensar en cualquier situación en la que¿Hay alguna razón para no usar std :: make_shared al construir objetos?

std::shared_ptr<Object> obj(new Object("foo", 1)); 

sería preferible

auto obj = std::make_shared<Object>("foo", 1); 

El último siempre resulta en una mejor localidad y reduce la fragmentación de memoria. ¿Hay alguna situación en la que prefiera (o se vea forzado) utilizar el primer formulario, excepto la interfaz con el código que devuelve los punteros sin procesar?

+4

Supongo que consideraría convertir de 'std :: unique_ptr ' para interactuar con punteros crudos? Porque creo que este es el tipo canónico que se devolverá de las funciones de fábrica. ¿Qué otros punteros se considerarían "punteros crudos" y tienen un lugar en el C++ moderno después de todo? –

Respuesta

18

Esto último siempre da como resultado una mejor ubicación y reduce la fragmentación de la memoria.

No siempre. Se recomienda que una implementación use una única asignación para el objeto contado de referencia y el recuento de referencia, pero no es requerido para hacerlo.

¿Por qué no quieres usar std::make_shared? Considere el caso donde tiene un objeto grande dinámicamente asignado que quiere que sea propiedad de std::shared_ptr y sabe que habrá referencias débiles a este objeto que probablemente sobrevivirán a las fuertes referencias al objeto (quizás haya muchas referencias débiles y solo una o dos referencias fuertes efímeras). En este caso, std::make_shared sería una mala elección, suponiendo que asigna un único bloque que posee tanto el objeto como el recuento de referencia: el bloque asignado (que es grande, recuerde) no puede destruirse hasta que no haya referencias débiles dejados al objeto.

Si va a asignar dinámicamente el objeto usted mismo y pasar el puntero al constructor std::shared_ptr, la memoria ocupada por el objeto podría liberarse tan pronto como no queden referencias fuertes, incluso si todavía hay referencias débiles.

+0

Ese es un buen punto. Ahora que lo pienso, el recuento de referencias coalescente con un objeto también puede dar lugar a la compartición falsa, lo que puede afectar el rendimiento en el escenario de subprocesos múltiples. –

0

Si está construyendo un objeto que tendrá varias entidades compartiendo durante la vida útil del objeto, entonces sí, desea preferir usar std :: make_shared siempre que sea posible. Es posible que algunos lugares no sean posibles si obtiene el puntero de otra persona; por ejemplo, una fábrica puede devolver un puntero sin formato o un std :: unique_ptr que le gustaría almacenar en un shared_ptr, lo que impide el uso de make_shared.

La pregunta en el título es un poco diferente; Hay muchas razones por las que no querrá usar shared_ptr para sus objetos. Solo debe usar shared_ptr si la vida es realmente compartida por varios objetos. De lo contrario, prefiere la pila asignando el objeto o usando unique_ptr.

0

Los IDE modernos tienen la función "Encontrar usos". Si usa std::make_shared para construir el objeto, cuando busca los lugares donde se llama al constructor de ese objeto, IDE no mostrará los lugares donde se usa std::make_shared.

Cuestiones relacionadas