H.Hassane
H.Hassane

Reputation: 3

strange issue with static method of a class template

I want to create a class template factory with c++/qt that can create different objects with a key

So I created a class named CFactory that will create CComponent which is derived from CBaseComponent

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();
 }

When I build this error I get (translated from French):

Error LNK2019 unresolved external symbol "public: static void __cdecl Factory::Register(class QString,class CBaseComponent *)" (?Register@?$Factory@VCBaseComponent@@VQString@@@@SAXVQString@@PAVCBaseComponent@@@Z) referenced in function _main TemplateFactoryDemo D:\trv\TemplateFactoryDemo\main.obj 1

Upvotes: 0

Views: 391

Answers (1)

E4z9
E4z9

Reputation: 1767

You have to define the templated member functions in the header file. Basically move everything from your Factory.cpp to Factory.h.

((*it).second)->Clone(); is also somehow fishy, probably you are confused by the fact that std::map et al are using pair<const K, V> as value_type, which is not the case for QMap. You probably mean (*it)->Clone() or it.value()->Clone().

Upvotes: 1

Related Questions