كيفية الحصول على كائن من فئة غير معروفة مع اسم classnam

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

  •  20-09-2019
  •  | 
  •  

سؤال

أنا أبحث عن طريقة لتحديد وقت التشغيل ، أي نوع من الكائنات يجب تخصيصه (استنادًا إلى اسم فئة معين ، وهو من النوع const char*).

حسنًا ، أبسط طريقة بالطبع هي استخدام الكثير من ifس /else ifS ، لكن هذا لا يبدو قابلاً للتطبيق ، لأن لدي أكثر من 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. أنا شخصيا أحب هذا طريقة

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