c++ - ¿Hay inconvenientes con el uso de make_shared para crear un shared_ptr
boost shared-ptr (5)
¿Hay algún inconveniente con el uso de make_shared<T>()
lugar de usar shared_ptr<T>(new T)
.
Aumentar los estados de documentación
Ha habido solicitudes reiteradas de usuarios para una función de fábrica que crea un objeto de un tipo determinado y le devuelve un shared_ptr. Además de la conveniencia y el estilo, dicha función también es excepcionalmente segura y considerablemente más rápida porque puede usar una única asignación tanto para el objeto como para su bloque de control correspondiente, eliminando una porción significativa de la sobrecarga de construcción de shared_ptr. Esto elimina una de las principales quejas de eficiencia sobre shared_ptr.
Además de los puntos presentados por @deft_code, uno aún más débil:
- Si usa
weak_ptr
s que viven después de que todos losshared_ptr
s de un objeto determinado han muerto, la memoria de este objeto vivirá en la memoria junto con el bloque de control hasta que falle el último weak_ptr. En otras palabras, el objeto se destruye pero no se desasigna hasta que se destruye el últimoweak_ptr
.
Además, make_shared
no es compatible con el patrón de fábrica . Esto se debe a que la llamada a make_shared
dentro de su función de fábrica llama al código de la biblioteca, que a su vez llama new
, al que no tiene acceso, ya que no puede llamar al constructor privado de la clase (el (los) constructor (es) deben ser privados , si sigues el patrón de fábrica correctamente).
De http://www.codesynthesis.com/~boris/blog/2010/05/24/smart-pointers-in-boost-tr1-cxx-x0/
El otro inconveniente de la implementación make_shared () es el aumento en el tamaño del código objeto. Debido a la forma en que se implementa esta optimización, se creará una instancia de una tabla virtual adicional, así como un conjunto de funciones virtuales para cada tipo de objeto que utilice con make_shared ().
Sé de al menos dos.
- Debe tener el control de la asignación. No es muy grande en realidad, pero a algunas aplicaciones antiguas les gusta devolver los indicadores que debes eliminar.
- Sin eliminación personalizada No sé por qué esto no es compatible, pero no lo es. Eso significa que sus punteros compartidos tienen que usar un eliminador de vainilla.
Bastante puntos débiles. así que trate de usar siempre make_shared.
Con make compartido no puede especificar cómo se realizará la asignación y la desasignación del objeto retenido.
Cuando se desee, use std::allocate_shared<T>
lugar:
std::vector<std::shared_ptr<std::string>> avec;
std::allocator<std::string> aAllocator;
avec.push_back(std::allocate_shared<std::string>(aAllocator,"hi there!"));
Tenga en cuenta que el vector no necesita ser informado sobre el asignador.
Para hacer un asignador personalizado, mira aquí https://.com/a/542339/1149664