3

我正在寻找一种方法来确定在运行时应该分配哪种类型的对象(基于给定的类名,它是 type const char*)。

好吧,最简单的方法当然是使用大量的ifs / 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变量或函数可以解决此问题,但会增加大量工作(当然您可以为此使用宏,但如果您已经在使用宏,您也可以使用另一个对象工厂方法)

4

4 回答 4

3

你不能直接声明吗

template<typename TBase, typename TDerived, typename TArg, typename... TArgs>

?

然后您可以专门针对以下情况

typename TBase, typename TDerived, typename TArg
于 2010-01-15T22:32:17.680 回答
2

在这里阅读答案,您可能需要一个工厂。

于 2010-01-15T22:36:02.773 回答
1

制作一个没有可变参数模板的专用 get_classobject() 怎么样?那将停止递归。

然后,您将有一个带有可变参数模板的定义,另一个是template<typename TBase, typename TDerived>. 另一个想法是创建一个仅接受 const char* 并返回 0 的非模板重载。

于 2010-01-15T22:37:33.707 回答
0

这听起来像是您正在寻找经典的对象工厂模式。看看这个stackoverflow 问题。我个人喜欢这种方法

于 2010-01-15T22:36:04.817 回答