Ich versuche, eine abstrakte Factory-Vorlage für mehrere abstrakte Fabriken in C++ zu erstellen und kam damit auf.C++ Abstract Factory mit Vorlagen
#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;
}
Es kompiliert und läuft ohne Speicherlecks (win32 crtdbg) in Ordnung, aber ich weiß nicht, ob dies wirklich der richtige Weg ist eine abstrakte Fabrik Vorlage zu tun.
temp.Register("DA", (Creator<Base>*)new DerivedCreator<DerivedA>);
Ich frage mich auch über die Zeile oben. Ich bin verwirrt, warum ich wirken muss. Ich verstehe Vorlagen nicht sehr gut, aber ich würde annehmen, dass es gut funktionieren sollte, wenn man bedenkt, dass sowohl die Template-Klasse als auch die tatsächliche Klasse abgeleitet sind.
Dieser Code funktioniert tatsächlich gut, wie oben gezeigt, und löscht sogar gut ohne Speicherverluste. Ich fühle mich einfach nicht wohl dabei.
ich nicht in der Lage gewesen, mit Ausnahme dieses von Mango keine realen Beispiele von Template-Klassen zu finden (wow Emulator) - https://mangos.svn.sourceforge.net/svnroot/mangos/trunk/src/framework/Dynamic/ObjectRegistry.h
Aber ich glaube nicht, dass ich diese Methode in meinem Projekt verwenden kann, weil ich plane, auf die Verwendung von DLLs an einem bestimmten Punkt in meinem Projekt und es verwendet CRTP, die gegen meine Anforderung für Laufzeitpolymorphismus ist.
Yep, die Zeile geschrieben Sie ist schlecht. Es gibt keine Beziehung zwischen den beiden Arten. Sie sind auf verschiedene Arten spezialisiert. Ich bin mir auch nicht sicher, warum Sie sich überhaupt mit CRTP beschäftigen. Normalerweise wird es verwendet, um * virtuelle * Funktionen zu vermeiden. Aber Sie haben immer noch diese, also warum mit den Vorlagen kümmern? – jalf
Nun, was ich versuche, ist eine 3-teilige Lösung zu erstellen. Programm, Bibliothek und DLL. Die DLL enthält die Implementierung, die Bibliothek enthält die Factory und das Programm verwendet die Schnittstelle. Die Vorlage existiert, weil ich das viel tun werde. Ich benutze es, um die Treiberauswahl meiner aktuellen Spiel-Engine zu ersetzen. Momentan gibt es einen Code zum Kopieren/Einfügen für Video, Physik, Eingabe und Audio. – NtscCobalt