Asignador C++ STL vs operador nuevo
memory new-operator (2)
Los dos no son contradictorios. Los asignadores son un PolicyPattern o StrategyPattern utilizados por los adaptadores de contenedor de las bibliotecas STL para asignar trozos de memoria para su uso con objetos.
Estos asignadores a menudo optimizan la asignación de memoria permitiendo que se asignen * rangos de elementos a la vez, y luego se inicialicen utilizando una nueva ubicación * elementos que se seleccionarán de pilas secundarias especializadas según el tamaño de bloque
De una forma u otra, el resultado final será (casi siempre) que los objetos se asignen con nuevos (ubicación o valor predeterminado)
Otro ejemplo vívido sería cómo, por ejemplo, boost library implementa smartpointers. Debido a que los smartpointers son muy pequeños (con poca sobrecarga), la sobrecarga de asignación puede convertirse en una carga. Tendría sentido que la implementación definiera un asignador especializado para hacer las asignaciones, por lo que uno puede tener un std :: set <> eficiente de smartpointers, std :: map <..., smartpointer> etc.
(Ahora estoy casi seguro de que boost realmente optimiza el almacenamiento para la mayoría de los smartpointers al evitar cualquier virtual, por lo tanto, vft, lo que hace que la clase sea una estructura POD, con solo el puntero sin procesar como almacenamiento; parte del ejemplo no se aplicará. , extrapolar a otros tipos de puntos inteligentes (refcontar puntos inteligentes, punteros a funciones miembro, punteros a funciones miembro con referencia de instancia, etc.))
De acuerdo con C ++ Primer edición 4, página 755, hay una nota que dice:
Los programas modernos de C ++ normalmente deberían usar la clase asignadora para asignar memoria. Es más seguro y más flexible.
No entiendo muy bien esta afirmación. Hasta ahora, todos los materiales que leí se enseñan usando new
para asignar memoria en C ++. En el libro se muestra un ejemplo de cómo la clase vectorial utiliza el asignador. Sin embargo, no puedo pensar en otros escenarios.
¿Alguien puede ayudar a aclarar esta afirmación? y dame mas ejemplos? ¿Cuándo debo usar el asignador y cuándo usar el new
? ¡Gracias!
Para la programación general, sí debes usar new
y delete
.
Sin embargo, si estás escribiendo una biblioteca, ¡no deberías! No tengo su libro de texto, pero me imagino que se trata de asignadores en el contexto de escribir el código de la biblioteca.
Los usuarios de una biblioteca pueden querer controlar exactamente qué se asigna desde dónde. Si todas las asignaciones de la biblioteca fueran new
y delete
, el usuario no tendría forma de tener ese nivel de control detallado.
Todos los contenedores STL toman un argumento de plantilla de asignador opcional. El contenedor utilizará ese asignador para sus necesidades de memoria interna. De forma predeterminada, si omite el asignador, usará std::allocator
que usa new
y delete
(específicamente, ::operator new(size_t)
y ::operator delete(void*)
).
De esta manera, el usuario de ese contenedor puede controlar desde dónde se asigna la memoria si lo desean.
Ejemplo de implementación de un asignador personalizado para su uso con STL y explicación: Mejora del rendimiento con asignadores de grupo personalizados para STL
Nota al margen : El enfoque de STL para los asignadores no es óptimo de varias maneras. Recomiendo leer Hacia un mejor modelo de asignación para una discusión de algunos de esos temas.