Допустим, у нас есть:
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<>
единственное решение?
заранее спасибо
Каждый владелец может использовать этот указатель для доступа к другим элементам в векторе.
Помимо того, что ужасная идея, вы могли бы реализовать ее с std::list
, хоть:
Во-первых, каждый экземпляр владельца получает итератор в список, а не указатель на сегмент. std::list
имеет преимущество в том, что при вставке / удалении не отменяются итераторы, если только вы не удалите элемент, на который указывает итератор.
С помощью этого итератора вы можете найти другие элементы в списке. Однако остается одна проблема: вам нужно безопасно определить начало и конец списка. Таким образом, вам нужны значения дозорного в начале и конце, которые могут быть e. г. нулевые указатели, если их нет в списке.
Одно важное замечание: если вам нужно удалить сегмент из списка, хотя у владельца все еще есть итератор, вам нужно найти способ сообщить владельцу об аннулировании итератора. Нет никаких средств, чтобы сделать это автоматически!
Если вам нужен произвольный доступ, но вам нужен контейнер, чтобы расти без аннулирования указателей / ссылок / итераторов на элементы, тогда вы можете использовать std::deque
. Это позволит вам расти / уменьшаться спереди или сзади. Если вы вставляете / удаляете из середины, это может сделать недействительными итераторы.