C ++: обновление указателей в глубокой копии (эффективно) - PullRequest
1 голос
/ 23 августа 2010

Мой вопрос лучше всего иллюстрируется примером кода, поэтому давайте начнем с этого:

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)), а потом, возможно, взгляну на это позже, если это окажется проблемой.Однако это не было бы хорошим ответом на мой вопрос, так как я явно просил о лучшей производительности.Не желая больше оставлять ответы непринятыми, я выбрал наиболее полезный ответ и принял его.

Ответы [ 2 ]

3 голосов
/ 23 августа 2010

Храните указатели как индексы.Как вы говорите, все они указывают на m_Cards, который является вектором, который можно индексировать (это правильный английский?).Либо вы делаете это только для хранения и преобразования их обратно в указатели при загрузке.Или вы можете подумать об использовании индексов вообще вместо указателей.

0 голосов
/ 23 августа 2010

А как вести индекс элементов карт вместо указателя:

vector<int> m_indexes;

...

Card* ptr = &m_cards[m_indexes[0]];

Вектор с индексами можно копировать без изменений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...