Элемент pop-push из std::vector и повторное использование элементов
У меня есть проект на C++03, который имеет проблему со структурой данных: я использую вектор вместо списка, даже если мне нужно постоянно pop_front-push_back. но сейчас это нормально, потому что мне нужно переписать слишком много кода на данный момент.
Мой подход заключается в том, что у меня всегда обновляется буфер последней точки frame_size. таким образом, каждый кадр должен выдвигаться вперед и отталкиваться назад. (возможно, есть название для этого подхода?)
поэтому я использую этот код:
Point apoint; // allocate new point
apoint.x = xx;
apoint.y = yy;
int size = points.size()
if (size > frame_size) {
this->points.erase( points.begin() ); // pop_front
}
this->points.push_back(apoint);
у меня есть некоторый готовый к использованию код для пула объектов, и поэтому я подумал: это не очень хорошая оптимизация, но я могу сохранить фронт в пуле и, таким образом, я могу получить время выделения точки.
Хорошо, это не так полезно, и, вероятно, это не имеет никакого смысла, но я спрашиваю только об образовательном любопытстве: как я могу это сделать?
Как я могу сохранить в памяти стертый элемент вектора для его повторного использования? имеет ли этот вопрос смысл? если нет, то почему?
.. поскольку стирание не возвращает стертый вектор, оно возвращает:
Итератор произвольного доступа, указывающий на новое местоположение элемента, который следует за последним элементом, стертым при вызове функции, который является концом вектора, если операция стерла последний элемент в последовательности.
2 ответа
у меня есть готовый код для пула объектов... как я могу это сделать?
Используя вектор, вы не можете. Вектор хранит свои элементы в непрерывном массиве, поэтому их нельзя размещать по одному, только в блоках произвольного размера. Следовательно, вы не можете использовать пул объектов в качестве распределителя для std::vector
,
Как я могу сохранить в памяти стертый элемент вектора для его повторного использования? имеет ли этот вопрос смысл? если нет, то почему?
Вектор уже делает это. Ваш звонок в erase
перемещает все элементы вниз в пространство, освобожденное первым элементом, оставляя пустое пространство в конце, чтобы вставить новый элемент в.
Пока вы используете вектор, вы не можете избежать перемещения всех элементов, когда стираете первый; если это слишком неэффективно, используйте deque
(или, возможно, list
) вместо
Я не уверен, что понимаю, что вы хотите сделать, но это должно быть функционально эквивалентно тому, что вы написали, без создания временного Point
пример:
// don't do this on an empty vector
assert (points.size() > 0);
// rotate elements in the vector, erasing the first element
// and duplicating the last one
copy (points.begin()+1, points.end(), points.begin());
// overwrite the last element with your new data
points.back().x = xx;
points.back().y = yy;
РЕДАКТИРОВАТЬ: Как отметил Майк Сеймур в комментариях, ни это решение, ни подход, предложенный в вопросе, не вызывает никакого нового распределения памяти.