كيفية الحصول على كائن من فئة غير معروفة مع اسم classnam
-
20-09-2019 - |
سؤال
أنا أبحث عن طريقة لتحديد وقت التشغيل ، أي نوع من الكائنات يجب تخصيصه (استنادًا إلى اسم فئة معين ، وهو من النوع const char*
).
حسنًا ، أبسط طريقة بالطبع هي استخدام الكثير من if
س /else if
S ، لكن هذا لا يبدو قابلاً للتطبيق ، لأن لدي أكثر من 100 فئة مختلفة (على الأقل أنها جميعها مستمدة من فئة قاعدة واحدة) ، وعلي أن أضيف فصولًا جديدة بشكل منتظم.
لقد توصلت بالفعل إلى مسودة أولى ، لكن للأسف لم يتم تجميعها بعد (Mingw & G ++ 4.4)
template<typename TBase, typename TDerived, typename... TArgs>
Base* get_classobject(const char* classname)
{
if(strcmp(classname,typeid(TDerived).name())==0)
return new TDerived; //
else if(sizeof...(TArgs)>0)
return get_classobject<TBase,TArgs...>(classname);
else
return 0;
}
int main()
{
Base* obj = get_classobject<Base,A,Foo,B,C>("Foo");
// ^- Types A B C and Foo are all derived from Base
delete obj; //of course we got an virtual dtor ;)
return 0;
}
لكن ذلك sizeof...(TArgs)>0
لا يمنع GCC من محاولة إنشاء التعليمات البرمجية ل get_classobject<TBase,const char*>(const char*)
الذي يفشل
هل لديك أي فكرة ، كيفية إصلاح هذا ، أو أي فكرة أخرى؟ شكرًا.
تحرير: لقد قمت بحلها:
template<typename TBase, typename TDerived>
Base* get_classobject(const char* classname)
{
if(strcmp(classname,typeid(TDerived).name())==0)
return new TDerived;
return 0;
}
template<typename TBase, typename TDerived, typename TArg, typename... TArgs>
Base* get_classobject(const char* classname)
{
if(strcmp(classname,typeid(TDerived).name())==0)
return new TDerived;
return get_classobject<TBase,TArg,TArgs...>(classname);
}
تحرير للقراء المهتمين:
يجب عليك الآن أن يكون التنفيذ أعلاه غير مستقل على الإطلاق. إخراج typeif(sometype).name()
هو برنامج التحويل البرمجي/التنفيذ محدد. باستخدام static const char* name
متغير أو وظيفة داخل جميع الفئات المشتقة ، من شأنه إصلاح هذا ، ولكنه يضيف مجموعة من العمل (بالطبع يمكنك استخدام ماكرو لهذا الغرض ، ولكن إذا كنت تستخدم وحدات الماكرو بالفعل ، فيمكنك استخدام طريقة مصنع كائن أخرى)
المحلول
لا يمكنك أن تعلن فقط
template<typename TBase, typename TDerived, typename TArg, typename... TArgs>
?
ثم يمكنك التخصص في حالة
typename TBase, typename TDerived, typename TArg
نصائح أخرى
اقرأ الإجابات هنا, ، من المحتمل أن تحتاج إلى مصنع.
ماذا عن صنع get_classobject () متخصصة مع عدم وجود تلبس متغير؟ من شأنه أن يوقف العودية.
عندها سيكون لديك تعريف واحد مع قالب متغير ، وآخر من العدل template<typename TBase, typename TDerived>
. فكرة أخرى هي جعل الحمل الزائد غير المملوك يقبل فقط const char*، وإرجاع 0.
هذا يبدو أنك تبحث عن نمط مصنع الكائن الكلاسيكي. الق نظرة على هذا سؤال stackoverflow. أنا شخصيا أحب هذا طريقة