Мой вопрос лучше всего иллюстрируется примером кода, поэтому давайте начнем с этого:
class Game
{
// All this vector does is establish ownership over the Card objects
// It is initialized with data when Game is created and then is never
// changed.
vector<shared_ptr<Card> > m_cards;
// And then we have a bunch of pointers to the Cards.
// All these pointers point to Cards from m_cards.
// These could have been weak_ptrs, but at the moment, they aren't
vector<Card*> m_ptrs;
// Note: In my application, m_ptrs isn't there, instead there are
// pointers all over the place (in objects that are stored in member
// variables of Game.
// Also, in my application, each Card in m_cards will have a pointer
// in m_ptrs (or as I said, really just somewhere), while sometimes
// there is more than one pointer to a Card.
}
Теперь я хочу сделать глубокую копию этого класса Game.Я создаю новый вектор с новыми shared_ptrs, которые указывают на новые объекты Карты, которые являются копиями оригинальных объектов Карты.Эта часть проста.
Затем начинается проблема, указатели m_ptrs должны быть обновлены, чтобы указывать на карты в m_cards, что является непростой задачей.Для этого необходимо создать карту и заполнить ее во время копирования m_cards (с map[oldPtr] = newPtr
), а затем использовать ее для обновления m_ptrs.Однако это всего лишь O(m * log(n))
(m = m_ptrs.size(); n = m_cards.size()
).Поскольку это будет довольно регулярная операция *, я хотел бы сделать это эффективно, и у меня есть ощущение, что это возможно в O(m)
с использованием пользовательских указателей.Тем не менее, я не могу найти эффективный способ сделать это.Кто-нибудь, кто это делает?
* он используется для создания испытательного стенда для ИИ, позволяя ему "пробовать" различные ходы
Редактировать: Я хотел бы добавить немного при принятииответь, как я еще неЯ жду, пока не вернусь к этому проекту (я попал на боковую дорожку, так как слишком много работал над этим проектом - если вы делаете это ради удовольствия, это должно оставаться забавным), так что может пройти некоторое время, прежде чем я примуответ.Тем не менее, я приму ответ через некоторое время, так что не волнуйтесь: P
Редактировать номер 2: Я до сих пор не вернулся к этому проекту.Сейчас я думаю о том, чтобы просто пойти по пути O(m * log(n))
и не жаловаться, а потом посмотреть, нужно ли это быстрее.Однако, поскольку недавно я потратил некоторое время на изучение своих паттернов, я также думаю, что мне действительно нужно как-то реорганизовать этот проект.О, и что я мог бы просто потратить некоторое время на работу над этой проблемой со всеми новыми знаниями, которые у меня есть за поясом.Так как нет ответа, который говорит: «Просто придерживайтесь hashmap и посмотрите позже, действительно ли он должен быть быстрее» (и я был бы на самом деле довольно разочарован, если бы был, поскольку это не ответ на мой вопрос), яеще немного отложить выбор ответа, пока я не вернусь к этому проекту.
Редактировать номер 3: Я все еще не вернулся к этому проекту.Точнее, он был отложен на неопределенный срок.Я почти уверен, что сейчас я бы не стал слишком сильно склонять голову над O(m * log(n))
, а потом, возможно, взгляну на это позже, если это окажется проблемой.Однако это не было бы хорошим ответом на мой вопрос, так как я явно просил о лучшей производительности.Не желая больше оставлять ответы непринятыми, я выбрал наиболее полезный ответ и принял его.