Ejemplo del mundo real: std::vector
asigna memoria más que suficiente para almacenar su carga actual, para reducir el costo promedio de push_back
.
Si almacenó un búfer T*data
, llamar a data=new T[capacity]
crearía por defecto una carga de objetos T
. El problema es que la semántica de vector
es que solo contiene lo que has puesto en ella: podemos preasignar memoria para nuestros objetos, pero esos objetos no deberían existir aún.
La solución es hacer que el miembro vector::data
sea un void*
y asignarle memoria sin tipo. Ahora, siempre que agreguemos un objeto al contenedor, debemos construirlo para que este objeto exista y darle sentido al puntero sin procesar.
template <typename T>
void vector <T> :: push_back (const T & value)
{
resize (m_size + 1);
// construct a new T in the void buffer.
new (reinterpret_cast <T*> (m_data) + m_size) T (value);
++ m_size;
}
template <typeame T>
void vector <T> :: pop_back()
{
(reinterpret_cast <T*> (m_data) + m_size) -> ~ T();
-- size;
}
Como dicen las respuestas, es una ubicación nueva. La razón * práctica * para escribir esto podría ser proporcionar una interfaz compatible con C a una biblioteca C++, aunque otros usos (como mi ejemplo std :: vector) son un poco más convencionales. – spraff