Template Factory Pattern in C++

隐身守侯 提交于 2019-12-23 04:03:33

问题


I am trying to make a factory that will have the type passed in, rather then having it hard coded for types. However, when I attempt to add the type to the factory inside of the types .cpp file, I will get a linker error. For example, he is a linker error I am currently getting.

1>RandomClass.obj : error LNK2019: unresolved external symbol "public: short __thiscall TemplatedFactory::AddType(char const *)" (??$AddType@VRandomClass@@@TemplatedFactory@@QAEFPBD@Z) referenced in function "void _cdecl `dynamic initializer for 'private: static short RandomClass::ID''(void)" (??_E?ID@RandomClass@@0FA@@YAXXZ)

I tried to make the test case as small as possible, though it does cross five files, they are very small

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

I can remove the the linker error if I move

short RandomClass::ID = TemplatedFactory::GetInstance().AddType<RandomClass>("RandomClass");

from RandomClass.cpp to TemplatedFactory.cpp, however, I would like to have the declaration in RandomClass.cpp. Does anyone know of a way to fix this or perhaps a better design (without the use of external libraries).


回答1:


Templated functions cannot have their definition and declaration separated from each other without export, which your compiler probably doesn't support. You need to move the TemplateFactory::AddType definition to the header.




回答2:


You cannot place implementation of class template in cpp-file See some technique for "cheating" on http://www.parashift.com/c++-faq-lite/templates.html#faq-35.14



来源:https://stackoverflow.com/questions/5185502/template-factory-pattern-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!