我想用c ++ / qt创建一个类模板工厂,它可以用键创建不同的对象
所以我创建了一个名为CFactory的类,它将创建从CBaseComponent派生的CComponent
Factory.h
#ifndef FACTORY_H
#define FACTORY_H
#include "Header.h"
template <class Object, class Key = QString> class Factory
{
static QMap<Key, Object*> m_map;
public:
static void Register(Key key, Object* obj);
Object* Create(const Key& key);
};
#endif // FACTORY_H
Factory.cpp
#include "factory.h"
template <class Object, class Key> QMap<Key, Object*> Factory<Object, Key>::m_map = QMap<Key, Object*>();
template <class Object, class Key> void Factory<Object, Key>::Register(Key key, Object* obj)
{
if (m_map.find(key) == m_map.end())
{
m_map[key] = obj;
}
}
template <class Object, class Key> Object* Factory<Object, Key>::Create(const Key& key)
{
Object* tmp = 0;
typename QMap<Key, Object*>::iterator it = m_map.find(key);
if (it != m_map.end())
{
tmp = ((*it).second)->Clone();
}
return tmp;
}
BaseComponent.h
#ifndef BASECOMPONENT_H
#define BASECOMPONENT_H
#include "Header.h"
class CBaseComponent
{
public:
CBaseComponent(){};
~CBaseComponent(){};
};
#endif
Component.h
#ifndef COMPONENT_H
#define COMPONENT_H
#include "BaseComponent.h"
class CComponent :
public CBaseComponent
{
public:
CComponent(){};
~CComponent(){};
};
#endif
Main.cpp的
#include "templatefactorydemo.h"
#include <QtWidgets/QApplication>
#include "Factory.h"
#include "Component.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Factory<CBaseComponent> fac;
Factory<CBaseComponent>::Register(QString("CComponent"), new CComponent);
CBaseComponent *c=fac.Create("CComponent");
return a.exec();
}
当我构建此错误时,我得到了(翻译自法语):
错误LNK2019未解析的外部符号&#34; public:static void __cdecl 厂::注册(类 QString,类CBaseComponent *)&#34; (?注册@?$ @厂@@ VCBaseComponent @@@@ VQString @@ SAXVQString @@@ PAVCBaseComponent Z) 在函数中引用 _main TemplateFactoryDemo D:\ trv \ TemplateFactoryDemo \ main.obj 1
答案 0 :(得分:1)
您必须在头文件中定义模板化成员函数。基本上移动从Factory.cpp
到Factory.h
的所有内容。
((*it).second)->Clone();
也有点可疑,可能你会被std::map
等使用pair<const K, V>
作为value_type
这一事实感到困惑,QMap
不是这种情况。 1}}。您可能需要(*it)->Clone()
或it.value()->Clone()
。