يتطلب Shared_PTR نوع كامل؛ لا يمكن استخدامه مع lua_state *

StackOverflow https://stackoverflow.com/questions/2433667

  •  19-09-2019
  •  | 
  •  

سؤال

أنا أكتب غلاف C ++ / OOP ل LUA. الرمز الخاص بي هو:

class LuaState
{
     boost::shared_ptr<lua_State> L;

     LuaState(): L( luaL_newstate(), LuaState::CustomDeleter )
     {
     }
}

المشكلة هي Lua_State غير مكتملة من النوع ويتطلب منشئ Shared_ptr من النوع الكامل. وأحتاج إلى تقاسم مؤشر آمن. (شيء مضحك يعزز المستندات يقول معظم الوظائف لا تتطلب نوعا كاملا، ولكن يتطلب المنشئ، لذلك لا توجد طريقة لاستخدامها. http://www.boost.org/doc/libs/1_42_0/libs/smart_ptr/smart_ptr.htm.)

هل يمكنني حل هذا؟ شكرا لك.

هل كانت مفيدة؟

المحلول

أنت تستخدم المسند الخاص بك، مما يعني أنه لا يتعين عليك الحصول على نوع كامل عند البناء. الشرط الوحيد هو ذلك CustomDeleter يمكن التعامل مع ذلك. (قد يؤدي تحويل المؤشر الذي تم تمريره إلى نوع كامل، على سبيل المثال (يقول من void* ل CompleteType*).

خلفية الاكتمال هي أنه بمجرد إنشاء shared_ptr يتم استدعاء مع DELETER الافتراضي، وسوف إنشاء فكر في الفئة التي تحتوي على الخط delete p; - ولهذا الرمز هو الصحيح، p يجب أن لا تكون غير مكتملة. سيتصل المدمر برمز المسجل هذا بشكل غير مباشر، لذلك لا يعتمد على اكتمال النوع.

ومع ذلك، إذا قمت بتمرير المسند الخاص بك، فسيتم تطبيق متطلبات Deleter الخاصة بك. تأكد من تحديد CustomDeleter بعد lua_State أصبح مكتمل.

نصائح أخرى

بدا غريبا boost::shared_ptr سيتطلب نوعا كاملا للميزة، لذلك كتبت هذا الاختبار الصغير الصغير الذي يظهر عكس ذلك (التعليمات البرمجية في النهاية).

أعتقد أن المشكلة ليست مع النوع الذي يحتاج إلى إكمال، ولكن مع الحجة الثانية التي تنتقلها إلى shared_ptr منشئ، يشبه وظيفة العضو. يجب أن تكون الحجة الثانية شيئا استقللا بوسيطة مؤشر واحدة. إذا كنت ترغب في استخدام وظيفة عضو في المجمع الخاص بك، يمكنك استخدامها boost::bind لتكييف الواجهة.

ربما تقصد؟:

 LuaState(): L( luaL_newstate(), boost::bind(LuaState::CustomDeleter,this,_1) )
 {
 }

مظاهرة أن boost::shared_ptr لا يتطلب أنواع كاملة:

// forward declarations
struct test;
test * create();
void destroy(test *);

// wrapper equivalent to the one in the question
struct wrapper {
   boost::shared_ptr<test> sp;
   wrapper() : sp( create(), destroy ) {}
};

// actual definitions
struct test {};
test * create() { return new test; }
void destroy(test *t) { delete t; }

// make it executable
int main() {
   test t;
}

بالنظر إلى أن Lua_State * لا يمكن استنساخه، هل نسخ كائن اللاحتف ذات مغزى؟ ما هي الدلالات المتوقعة لنسخ مثل هذا الكائن غير الموثوق به بطبيعته؟

السلوك الذي يبدو أنك تريده هو النسخ الضحلة - وأفضل طريقة للقيام بذلك هي ل Luastate أن تكون غير موثوقة وإدارة عمر Lua_State، ثم يمكنك تمرير الدولة ك shared_ptr<LuaState>.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top