Шаблон фабричного шаблона в C ++ - PullRequest
1 голос
/ 03 марта 2011

Я пытаюсь создать фабрику, в которой будет передан тип, а не жестко закодирован для типов.Однако, когда я пытаюсь добавить тип к фабрике внутри файла типов .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.Кто-нибудь знает способ исправить это или, возможно, лучший дизайн (без использования внешних библиотек).

Ответы [ 2 ]

7 голосов
/ 03 марта 2011

У шаблонных функций не может быть своего определения и объявления, отделенных друг от друга без export, что, вероятно, не поддерживается вашим компилятором.Вам нужно переместить определение TemplateFactory::AddType в заголовок.

2 голосов
/ 03 марта 2011

Вы не можете поместить реализацию шаблона класса в cpp-файл. См. Некоторую технику "обмана" на http://www.parashift.com/c++-faq-lite/templates.html#faq-35.14

...