C ++中的模板工厂模式

时间:2011-03-03 19:27:10

标签: c++ design-patterns templates metaprogramming factory-pattern

我正在尝试创建一个将传入类型的工厂,而不是将其硬编码为类型。但是,当我尝试将类型添加到类型.cpp文件内的工厂时,我将收到链接器错误。例如,他是我目前得到的链接器错误。

1> RandomClass.obj:错误LNK2019:未解析的外部符号“public:short __thiscall TemplatedFactory :: AddType(char const *)”(?? $ AddType @ VRandomClass @@@ TemplatedFactory @@ QAEFPBD @ Z)在函数中引用“void _ cdecl`'invate: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中有声明。有没有人知道解决这个问题的方法或者更好的设计(不使用外部库)。

2 个答案:

答案 0 :(得分:7)

如果没有export,模板化函数不能将它们的定义和声明彼此分开,编译器可能不支持它们。您需要将TemplateFactory::AddType定义移动到标题。

答案 1 :(得分:2)

您不能在cpp文件中放置类模板的实现 请参阅http://www.parashift.com/c++-faq-lite/templates.html#faq-35.14

上的“作弊”技巧