Я пытаюсь создать абстрактный шаблон фабрики для нескольких абстрактных фабрик на C++ и придумал это.C++ Abstract Factory с использованием шаблонов
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#include <map>
#include <stdio.h>
class Base
{
public:
virtual ~Base() {}
virtual bool Get() = 0;
};
class DerivedA : public Base
{
public:
bool Get()
{
return true;
}
};
class DerivedB : public Base
{
public:
bool Get()
{
return false;
}
};
template <class T>
class Creator
{
public:
virtual ~Creator(){}
virtual T* Create() = 0;
};
template <class T>
class DerivedCreator : public Creator<T>
{
public:
T* Create()
{
return new T;
}
};
template <class T, class Key>
class Factory
{
public:
void Register(Key Id, Creator<T>* Fn)
{
FunctionMap[Id] = Fn;
}
T* Create(Key Id)
{
return FunctionMap[Id]->Create();
}
~Factory()
{
std::map<Key, Creator<T>*>::iterator i = FunctionMap.begin();
while (i != FunctionMap.end())
{
delete (*i).second;
++i;
}
}
private:
std::map<Key, Creator<T>*> FunctionMap;
};
int main(int argc, char** argv[])
{
_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);
//Register
Factory<Base, char*> temp;
temp.Register("DA", (Creator<Base>*)new DerivedCreator<DerivedA>);
temp.Register("DB", (Creator<Base>*)new DerivedCreator<DerivedB>);
//Pointer to base interface
Base* pBase = 0;
//Create and call
pBase = temp.Create("DA");
printf("DerivedA %u\n", pBase->Get());
delete pBase;
//Create and call
pBase = temp.Create("DB");
printf("DerivedB %u\n", pBase->Get());
delete pBase;
return 0;
}
Он собирает и работает нормально, без каких-либо утечек памяти (win32 crtdbg), но я не знаю, действительно ли это правильный способ сделать абстрактный шаблон фабрики.
temp.Register("DA", (Creator<Base>*)new DerivedCreator<DerivedA>);
Я также интересуюсь строкой выше. Я смущен, почему я должен бросить. Я не очень хорошо разбираюсь в шаблонах, но я бы предположил, что он должен работать нормально, учитывая, что и класс шаблона, и фактический класс получены.
Этот код действительно работает нормально, как показано выше, и даже удаляет штраф без утечек памяти. Я просто не чувствую себя полностью комфортно.
Я не смог найти какие-либо реальные примеры шаблонных классов для этого, кроме как от MaNGOS (вау эмулятора) - https://mangos.svn.sourceforge.net/svnroot/mangos/trunk/src/framework/Dynamic/ObjectRegistry.h
Но я не думаю, что я могу использовать этот метод в моем проекте, потому что я планирую об использовании DLL в какой-то момент моего проекта и использует CRTP, который противоречит моему требованию полиморфизма времени выполнения.
Да, линия вы вывесили это плохо. Между этими двумя типами нет никакой связи. Они специализируются на разных типах. Я также не уверен, почему вы вообще беспокоитесь о CRTP. Обычно он используется для * исключения * виртуальных функций. Но у вас все еще есть такие, так зачем беспокоиться о шаблонах? – jalf 2010-12-05 05:36:16
Ну, что я пытаюсь сделать, это создать решение из 3 частей. Программы, библиотеки и библиотеки DLL. DLL будет содержать реализацию, Библиотека содержит фабрику, а программа использует интерфейс. Шаблон существует, потому что я буду делать это много. Я использую его для замены выбора драйвера текущего игрового движка. В настоящее время он имеет скопированный/вставленный код для видео, физики, ввода и аудио. – NtscCobalt 2010-12-05 05:53:24