Как правильно / эффективно обрабатывать указатели на элементы std :: vector?

Допустим, у нас есть:

std::vector<Segment*> segments;
...
Segment* dd = new Segment;
segments.emplace_back(dd);
Owner*   owner = getOwner();
owner->setSegmentPointer(&(segments.back());

Это не будет работать из-за Правила аннулирования итераторов.

Любое последующее добавление элемента к вектору segments сделает недействительными указатели, хранящиеся в owner, Как обойти эту проблему, сохранив время доступа std::vector<>? (Предполагая, что мы не можем использовать vector.resize заблаговременно). Это использовать std::map<> единственное решение?

заранее спасибо

0

Решение

Каждый владелец может использовать этот указатель для доступа к другим элементам в векторе.

Помимо того, что ужасная идея, вы могли бы реализовать ее с std::list, хоть:

Во-первых, каждый экземпляр владельца получает итератор в список, а не указатель на сегмент. std::list имеет преимущество в том, что при вставке / удалении не отменяются итераторы, если только вы не удалите элемент, на который указывает итератор.

С помощью этого итератора вы можете найти другие элементы в списке. Однако остается одна проблема: вам нужно безопасно определить начало и конец списка. Таким образом, вам нужны значения дозорного в начале и конце, которые могут быть e. г. нулевые указатели, если их нет в списке.

Одно важное замечание: если вам нужно удалить сегмент из списка, хотя у владельца все еще есть итератор, вам нужно найти способ сообщить владельцу об аннулировании итератора. Нет никаких средств, чтобы сделать это автоматически!

2

Другие решения

Если вам нужен произвольный доступ, но вам нужен контейнер, чтобы расти без аннулирования указателей / ссылок / итераторов на элементы, тогда вы можете использовать std::deque. Это позволит вам расти / уменьшаться спереди или сзади. Если вы вставляете / удаляете из середины, это может сделать недействительными итераторы.

1

По вопросам рекламы [email protected]