【发布时间】:2011-03-03 19:27:10
【问题描述】:
我正在尝试创建一个可以传入类型的工厂,而不是为类型硬编码。但是,当我尝试将类型添加到类型 .cpp 文件中的工厂时,我会收到链接器错误。例如,他是我目前遇到的链接器错误。
1>RandomClass.obj:错误 LNK2019:函数中引用的未解析外部符号“public:short __thiscall TemplatedFactory::AddType(char const *)”(??$AddType@VRandomClass@@@TemplatedFactory@@QAEFPBD@Z) "void _cdecl 'private: static short RandomClass::ID''的动态初始化器(void)" (??_E?ID@RandomClass@@0FA@@YAXXZ)
我试图使测试用例尽可能小,虽然它确实跨越了五个文件,但它们非常小
BaseClass.h : http://codepad.org/MhZMw7t0
#pragma once
class BaseClass{ };
RandomClass.h : http://codepad.org/xoObzP8G
#pragma once
#include "BaseClass.h"
class RandomClass : public BaseClass
{
private:
static short ID;
public:
RandomClass();
virtual ~RandomClass();
};
TemplatedFactory.h : http://codepad.org/qkcTBw24
#pragma once
#include <map>
using std::map;
#include "BaseClass.h"
template<typename Type> BaseClass* createType() { return new Type; }
class TemplatedFactory
{
private:
typedef BaseClass* (*ComponentFactoryFuncPtr)();
typedef map<const char*, ComponentFactoryFuncPtr> map_type;
map_type m_Map;
public:
static TemplatedFactory &GetInstance();
template<typename Type>
short AddType(const char* componentName);
};
RandomClass.cpp : http://codepad.org/ALoF3Ysb
#include "RandomClass.h"
#include "TemplatedFactory.h"
short RandomClass::ID = TemplatedFactory::GetInstance().AddType<RandomClass>("RandomClass");
RandomClass::RandomClass() { }
RandomClass::~RandomClass() { }
TemplatedFactory.cpp : http://codepad.org/iqgNqa6H
#include "TemplatedFactory.h"
TemplatedFactory &TemplatedFactory::GetInstance()
{
static TemplatedFactory instance;
return instance;
}
template<typename Type>
short TemplatedFactory::AddType(const char* componentName)
{
ComponentFactoryFuncPtr function = &createType<Type>;
m_Map.insert(std::make_pair(componentName, function));
return 0;
}
如果我移动,我可以删除链接器错误
short RandomClass::ID = TemplatedFactory::GetInstance().AddType<RandomClass>("RandomClass");
从 RandomClass.cpp 到 TemplatedFactory.cpp,但是,我希望在 RandomClass.cpp 中有声明。有谁知道解决这个问题的方法或者更好的设计(不使用外部库)。
【问题讨论】:
-
真正的
BaseClass至少有一个虚拟析构函数,对吧? -
如果为 RandomClass 添加一个实现到 TemplatedFactory.cpp 会发生什么?尝试将静态类变量链接到动态实现会成为问题。
标签: c++ design-patterns templates metaprogramming factory-pattern