2011-04-11 12 views
18

Según C++ Primer 4ª edición, página 755, hay una nota que dice:C++ STL asignador vs operador nueva

programas Moderno C++ normalmente debe utilizar la clase asignador para asignar memoria. Es más seguro y más fl exible.

No entiendo muy bien esta afirmación. Hasta ahora, todos los materiales que leo enseñan usando new para asignar memoria en C++. Un ejemplo de cómo se utiliza el asignador de clase de vector en el libro. Sin embargo, no puedo pensar en otros escenarios.

¿Alguien puede ayudar a aclarar esta afirmación? y dame más ejemplos? ¿Cuándo debo usar el asignador y cuándo usar new? ¡Gracias!

Respuesta

35

Para programación general, sí debe usar new y delete.

Sin embargo, si está escribiendo una biblioteca, ¡no debería! No tengo su libro de texto, pero me imagino que está discutiendo los asignadores en el contexto de escribir el código de la biblioteca.

Los usuarios de una biblioteca pueden querer tener control sobre exactamente qué se asigna desde dónde. Si todas las asignaciones de la biblioteca pasaron por new y delete, el usuario no tendría forma de tener ese nivel de control preciso.

Todos los contenedores STL toman un argumento opcional de plantilla de asignador. El contenedor usará 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 de dónde se asigna la memoria si lo desea.

Ejemplo de implementación de un asignador personalizado para su uso con STL, y explicación: Improving Performance with Custom Pool Allocators for STL

Nota al margen: El enfoque STL a los colocadores no es óptima de varias maneras. Recomiendo leer Towards a Better Allocator Model para una discusión de algunos de esos temas.

+4

+1 para el "enfoque de STL para asignadores no es óptimo" más el enlace a "Hacia un mejor modelo de adjudicador" :) –

+1

¡El enlace que proporcionó es muy útil! –

1

Los dos no son contradictorios. Los asignadores son un PolicyPattern o StrategyPattern utilizado por los adaptadores de contenedor de las bibliotecas STL para asignar trozos de memoria para su uso con objetos.

Estos asignadores optimizar con frecuencia asignación de memoria al permitir * gamas de elementos que se asignarán a la vez, y luego inicializan usando una colocación nueva * artículos que se selecciona entre montones secundarias, especializados dependiendo de bloque

Una forma u otra, el resultado final será (casi siempre) ser que los objetos se asignan con la nueva (colocación o por defecto)


otro ejemplo vivo sería cómo por ejemplo, impulsar la biblioteca implementa smartpointers. Debido a que los smartpointers son muy pequeños (con poca sobrecarga), la sobrecarga de asignación puede convertirse en una carga. No tendría sentido para la aplicación para definir un asignador especializado para hacer las asignaciones, por lo que uno puede tener std :: set eficiente <> de smartpointers, std :: mapa < ..., SmartPointer> etc.

(Ahora Estoy casi seguro de que el impulso realmente optimiza el almacenamiento para la mayoría de los smartpointers evitando cualquier virtual, por lo tanto, el vft, haciendo de la clase una estructura POD, con solo el puntero sin formato como almacenamiento; algunos ejemplos no se aplicarán. Pero, de nuevo, extrapolar a otros tipos de smartpointer (recuento de smartpointers, punteros a funciones de miembro, punteros a funciones de miembro con referencia de instancia, etc.))