私は、C++で複数の抽象ファクトリの抽象ファクトリテンプレートを作成しようとしています。C++ Abstractテンプレートを使用している工場
#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>);
私は上記の行についても不思議です。私はなぜキャストしなければならないのか混乱している。私は非常によくテンプレートを理解していないが、テンプレートクラスと実際のクラスの両方が派生していることを考えるとうまくいくはずだと思います。
実際には、コードは上記のように正常に動作し、メモリリークのない状態でも正常に削除されます。私はちょうどそれを完全に快適に感じることはありません。
私はマンゴー(すごいエミュレータ)からこれ以外テンプレートクラスの任意の実際の例を見つけることができていないからhttps://mangos.svn.sourceforge.net/svnroot/mangos/trunk/src/framework/Dynamic/ObjectRegistry.h
しかし、私は私が計画しているので、私は私のプロジェクトで、そのメソッドを使用することができるとは思いません私のプロジェクトのある時点でDLLを使用すると、実行時の多態性に関する私の要求に反するCRTPが使用されます。
うん、あなたが掲示ラインが悪い:
あなたは基本型は、それが派生型のインスタンスを作成することにより、
Creator<Base>
のインタフェースを実装することができますので、どのような派生テンプレートを伝える必要があります。 2つのタイプの間には関係がありません。彼らはさまざまなタイプに特化しています。私はCRTPをどうして迷っているのかも分かりません。通常は、仮想関数を避けるために使用されます。しかし、あなたはまだそれらを持っている、なぜテンプレートを気にする? – jalf私がしようとしているのは、3つの部分のソリューションを作成することです。プログラム、ライブラリ、およびDLL。 DLLには実装が含まれ、ライブラリにはファクトリが含まれ、プログラムではインターフェイスが使用されます。 私はこれをやっているので、テンプレートが存在します。私は現在のゲームエンジンのドライバ選択を置き換えるためにそれを使用しています。現在、ビデオ、物理、入力、およびオーディオ用のコピー/ペーストコードがあります。 – NtscCobalt