【问题标题】:strange issue with static method of a class template类模板的静态方法的奇怪问题
【发布时间】:2016-12-02 13:38:28
【问题描述】:

我想用c++/qt创建一个类模板工厂,可以用一个key创建不同的对象

所以我创建了一个名为 CFactory 的类,它将创建从 CBaseComponent 派生的 CComponent

工厂.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

组件.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 未解析的外部符号“public: static void __cdecl 工厂::注册(类 QString,类 CBaseComponent *)" (?Register@?$Factory@VCBaseComponent@@VQString@@@@SAXVQString@@PAVCBaseComponent@@@Z) 在函数中引用 _main TemplateFactoryDe​​mo D:\trv\TemplateFactoryDe​​mo\main.obj 1

【问题讨论】:

标签: c++ qt templates factory


【解决方案1】:

您必须在头文件中定义模板化的成员函数。基本上将所有内容从您的Factory.cpp 移动到Factory.h

((*it).second)-&gt;Clone(); 也有点可疑,您可能对std::map 等人使用pair&lt;const K, V&gt; 作为value_type 的事实感到困惑,而QMap 并非如此。你的意思可能是(*it)-&gt;Clone()it.value()-&gt;Clone()

【讨论】:

  • 感谢您的回复,它解决了问题,但我不明白为什么我必须将所有内容从 Factory.cpp 移动到 Factory.h ?你能解释更多吗?我的代码有什么问题。
  • c++ 编译器将每个“单元”彼此分开编译,其中 .cpp 文件就是这样一个单元。此外,模板化函数仅根据对它们所请求的具体类型的需求而生成。编译 Factory.cpp 时,不会生成任何内容,因为 Factory.cpp 或其包含的头文件中没有任何内容使用模板化函数。编译 main.cpp 时,编译器只知道 main.cpp 及其所有包含的文件,不包括 Factory.cpp,因此实际上没有为 main 中请求的具体类型生成来自 Factory.cpp 的函数定义。 cpp.
  • 函数 declarations 是生成的,因为它们在包含的 Factory.h 中。这就是 main.cpp 编译的原因,但是 linker 在链接可执行文件时抱怨缺少这些函数的定义。
猜你喜欢
  • 1970-01-01
  • 2011-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多