Я пишу игру и сопроводительный движок на C++. Двигатель в значительной степени зависит от автоматизации с использованием простого встроенного языка сценариев. Скрипты могут создавать классы объектов, определять на них прослушиватели событий и создавать экземпляры из них. В настоящее время экземпляр должен быть привязан к глобальному идентификатору сценария, чтобы сохранить его существование. Очевидным результатом этого является отсутствие анонимных объектов, которые, безусловно, будут наиболее распространены.Поддержание std :: set <boost :: shared_ptr>
В настоящее время экземпляры управляются с использованием 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<>
через свой базовый класс.
Может ли кто-нибудь рекомендовать подходящее обходное решение?
Edit:
Я сделал то, что должен был делать в первую очередь, и разделить поведение Instance
класса на два класса: Instance
и Reference
. Выражение new SomeClass
в сценарии затем возвращает Reference
к новому Instance
. Сами объекты Instance
никогда не управляются с помощью shared_ptr
, поэтому они несут ответственность за самоубийство в ответ на подходящее событие, например, конец анимации, конец уровня и т. Д.
Спасибо за помощь! Рефакторинг является таким же хорошим решением, как любой, если он просто работает.
Еще лучше, верните shared_ptr вместо исходного. – rlbond
В настоящий момент я возился с этим решением; в принципе create() только когда-либо вызывается для создания анонимных экземпляров и инициализирует экземпляр с установленным «анонимным» флагом. Если этот флаг не установлен, экземпляр по умолчанию выполняет insert() для shared_ptr для себя с нулевым делетером. В настоящее время я пытаюсь отследить загадочное исключение bad_weak_ptr, возникшее в результате изменения. –
* «Если этот флаг не установлен, экземпляр по умолчанию выполняет insert() для shared_ptr для себя» * Я не уверен, что именно вы делаете, но похоже, что он снова запустится в проблему, не может вызывать 'shared_from_this()' во время построения. Также обратите внимание, что 'shared_from_this()' работает только в том случае, если объект фактически хранится в shared_ptr где-то. Например, 'shared_from_this()' на статически выделенном экземпляре не будет работать. – sth