Поддержание std :: set - PullRequest
       11

Поддержание std :: set

2 голосов
/ 19 января 2010

Я пишу игру и сопутствующий движок на C ++.Движок сильно зависит от автоматизации с использованием простого встроенного языка сценариев.Скрипты могут создавать классы объектов, определять для них прослушиватели событий и создавать из них экземпляры.В настоящее время экземпляр должен быть связан с глобальным идентификатором сценария, чтобы сохранить свое существование.Очевидный результат этого заключается в том, что не может быть анонимных объектов, которые будут наиболее распространенными.

В настоящее время экземпляры управляются с использованием std::set<Instance*, spatial_sort>, где spatial_sort - это функтор, который сортируетэкземпляры по позиции, для рендеринга и обнаружения столкновений.Экземпляры удаляются и повторно вставляются в каждый кадр, используя их текущую позицию в качестве подсказки, при условии, что они вряд ли будут перемещаться целым лотом в пятидесятые секунды.Если в экземпляре установлен флаг dead, он удаляется из набора.Конструкторы и деструктор Instance вызывают insert(this) и erase(this) соответственно.

Чтобы разрешить анонимные экземпляры, я хочу изменить набор на std::set<boost::shared_ptr<Instance>, spatial_sort>, что позволило бы Instanceделиться правами собственности на экземпляры и сохранять их существование, пока они не уничтожат себя.К сожалению, поскольку вызовы insert() должны быть размещены в конструкторе, shared_from_this() не будет работать для получения shared_ptr для Instance.Неважно, что Instance уже наследуется от boost::enable_shared_from_this<> через его базовый класс.

Кто-нибудь может порекомендовать подходящий обходной путь?

Редактировать:

Я сделал то, что должен был сделать в первую очередь, и разделил поведение класса Instance на два класса: Instance и Reference.Выражение new SomeClass в скрипте возвращает Reference к новому Instance.Сами объекты Instance никогда не управляются с помощью shared_ptr, поэтому они отвечают за совершение самоубийства в ответ на подходящее событие, например, конец анимации, конец уровня и т. Д.

Спасибо заПомогите!Рефакторинг - это такое же хорошее решение, как и любое, если оно просто работает.

1 Ответ

2 голосов
/ 19 января 2010

Вы можете добавить статический метод к Instance, который затем будете использовать для создания новых объектов, а также выполнять административные функции, такие как добавление его в набор:

static Instance* create(int something) {
  boost::shared_ptr<Instance> sptr(new Instance(something));
  instanceset.insert(sptr);
  return sptr.get();
}

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

Подробнее об этом см. Также статью C ++ FAQ Lite о «Динамическое связывание во время инициализации» , которая не имеет прямого отношения, но использует ту же технику для обхода ограничений на использование виртуальных функций в конструкторы.

...