模板工厂给出链接器错误并忽略引用类型

Template factory giving linker error and ignoring reference type

本文关键字:错误 引用类型 链接 工厂      更新时间:2023-10-16

我正在为我的项目创建一个模板工厂,一切都很好,直到我需要在对象创建过程中添加一个额外的参数。

工厂有两个主要模板:

template <typename T>
class GenericFactory_c: boost::noncopyable
{
    public:
          typedef typename T::ObjectType_t ObjectType_t;
          //basic creating with just 1 parameter (object name)
          ObjectType_t Create(const String_c &className, const String_c &name) const
          {
              typename ObjectCreatorSet_t::const_iterator it = setObjectCreators.find(className, ObjectCreatorComp_s<T>());
              if(it == setObjectCreators.end())
                   PH_RAISE(OBJECT_NOT_FOUND_EXCEPTION, "[EntityFactory_c::Create]", name);
              return it->Create(name);
          }
          //"advanced" creation using an additional Y parameter
          template <typename Y>
          ObjectType_t Create(const String_c &className, const String_c &name, Y param) const
          {
              typename ObjectCreatorSet_t::const_iterator it = setObjectCreators.find(className, ObjectCreatorComp_s<T>());
              if(it == setObjectCreators.end())
                  PH_RAISE(OBJECT_NOT_FOUND_EXCEPTION, "[EntityFactory_c::Create]", name);
              return it->Create(name, param);
          }
          //rest of the code, probably irrelavent to the problem removed for clarity
};

其思想是,对于某些类型,将只使用带有2个参数的create,对于其他类型,将仅使用带有3个参数的create。

这意味着,对于某个Factory实例化,永远不会同时使用两个版本,只使用一个版本。

为了能够使用静态变量自动注册类型,我创建了一个ObjectCreator类,其定义如下:

template <typename T, typename Y>
class ObjectCreatorBase_c: public ObjectCreatorAutoUnlinkHook_t
{
    public:
         typedef T ObjectType_t;
         typedef Y ObjectCreatorProc_t;
    public:
         ObjectCreatorBase_c(const String_c &name, ObjectCreatorProc_t proc):
             strName(name),
             pfnCreateProc(proc)
         {
         }
         T Create(const String_c &name) const
         {
             return pfnCreateProc(name);
         }
         template <typename Z>
         T Create(const String_c &name, Z param) const
         {
             return pfnCreateProc(name, param);
         }
     //"irrelevant" code removed
         private:
             String_c strName;
             ObjectCreatorProc_t pfnCreateProc;
};

对于需要构造器上两个参数(字符串和实体引用)的EntityComponent类型,我定义了一个对象创建者如下:

template <typename T, typename Y>
class ObjectCreator1_c: public ObjectCreatorBase_c<T, T(*)(const String_c &, Y )>
{       
    public:
        ObjectCreator1_c(const String_c &name, ObjectCreatorProc_t proc):
            ObjectCreatorBase_c(name, proc)             
        {               
            GenericFactory_c<ObjectCreator1_c >::GetInstance().Register(*this);
        }
};

创造者是这样定义的:

static ObjectCreator1_c<EntityComponentPtr_t, Entity_c &> CreatorForXYZ_CreatorObject_gl("XYZ", &XYZ::Create);

工厂的定义如下:

typedef GenericFactory_c<ObjectCreator1_c<EntityComponentPtr_t, Entity_c &> > EntityComponentFactory_c;

最后,为了创建一个组件,我使用以下代码:

Entity_c::CreateCompXYZ()
{
    EntityComponentFactory_c &factory = EntityComponentFactory_c::GetInstance();
    EntityComponentPtr_t xyz = factory.Create("XYZ", "myXYZInstance", *this);
}

最后,我的问题来了,对于上面的代码,编译器似乎忽略了对*this的引用,并试图创建Entity对象的副本,而我得到了一个对Entity_c::Entity_c(const Entity_c &)的未定义引用,这没关系,因为Entity_c没有复制构造函数(不可复制),但问题是因为这段代码不应该尝试复制Entity_c,而是使用它引用。

有什么想法吗?

如果此函数

Entity_c::CreateCompXYZ()
{
    EntityComponentFactory_c &factory = EntityComponentFactory_c::GetInstance();
    EntityComponentPtr_t xyz = factory.Create("XYZ", "myXYZInstance", *this);
}

实际上正在为3参数Create 调用此模板

//"advanced" creation using an additional Y parameter
template <typename Y>
ObjectType_t Create(const String_c &className, const String_c &name, Y param) const

它实际上是试图复制CCD_ 6(此处为CCD_。

当然,如果它是不可复制的,这是行不通的!