الحفاظ على std :: set
-
21-09-2019 - |
سؤال
أنا أكتب لعبة ومحرك مصاحب في C ++. يعتمد المحرك اعتمادًا كبيرًا على الأتمتة باستخدام لغة البرمجة النصية المضمنة البسيطة. يمكن للنصوص إنشاء فئات كائنات ، وتحديد مستمعي الأحداث عليها ، وإنتاج مثيلات منها. في الوقت الحاضر ، يجب أن يكون مثيلًا مرتبطًا بمعرف Script-Global من أجل الحفاظ على وجوده. والنتيجة الواضحة لذلك هي أنه لا يمكن أن يكون هناك أشياء مجهولة ، والتي ستكون الأكثر شيوعًا إلى حد بعيد.
في الوقت الحاضر ، تتم إدارة الحالات باستخدام أ std::set<Instance*, spatial_sort>
, ، أين spatial_sort
هو functor الذي يفرز مثيلات عن طريق الموقف ، لتقديم واكتشاف الاصطدام. تتم إزالة الحالات وإعادة إدخال كل إطار باستخدام موضعها الحالي كتلميح ، على افتراض أنه من غير المحتمل أن يتحركوا كثيرًا في الخمسين من الثانية. اذا كان 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
, ، لذلك هم مسؤولون عن الانتحار استجابة لحدث مناسب ، على سبيل المثال ، نهاية الرسوم المتحركة ، نهاية المستوى ، إلخ.
شكرا للمساعدة! إن إعادة النية هي حل جيد مثل أي إذا كان يعمل فقط.
المحلول
يمكنك إضافة طريقة ثابتة إلى Instance
ثم تستخدمها لإنشاء كائنات جديدة والتي تقوم أيضًا بالأشياء الإدارية مثل إضافتها إلى المجموعة:
static Instance* create(int something) {
boost::shared_ptr<Instance> sptr(new Instance(something));
instanceset.insert(sptr);
return sptr.get();
}
إذا كنت ترغب في جعل هذا هو الطريقة الوحيدة لبناء كائن من هذه الفئة ، فيمكنك أيضًا جعل المنشئ الطبيعي خاصًا أو محميًا.
لمعرفة المزيد حول هذا ، انظر أيضًا إدخال C ++ Faq Lite حول "الربط الديناميكي أثناء التهيئة", ، وهو غير مرتبط بشكل مباشر ولكنه يستخدم نفس التقنية للعمل حول القيود المفروضة على استخدام الوظائف الافتراضية في البنائين.