Nts*_*alt 12 c++ templates factory-pattern
我正在尝试用C++为多个抽象工厂创建一个抽象工厂模板,并想出了这个.
#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;
}
Run Code Online (Sandbox Code Playgroud)
它编译并运行良好,没有内存泄漏(win32 crtdbg),但我不知道这是否真的是一个抽象工厂模板的正确方法.
temp.Register("DA", (Creator<Base>*)new DerivedCreator<DerivedA>);
Run Code Online (Sandbox Code Playgroud)
我也想知道上面这一行.我很困惑为什么我要演员.我不太了解模板,但我认为考虑到模板类和实际类都是派生的,它应该工作正常.
该代码实际上工作正常,如上所示,甚至删除没有内存泄漏罚款.我对它感到不舒服.
除了MaNGOS(哇模拟器)之外,我还没有找到任何模板类的真实例子 - https://mangos.svn.sourceforge.net/svnroot/mangos/trunk/src/framework/Dynamic/ObjectRegistry. H
但我不认为我可以在我的项目中使用该方法,因为我计划在我的项目中的某些时候使用DLL,它使用CRTP,这违反了我对运行时多态性的要求.
Pet*_*ham 13
该班DerivedCreator<DerivedA>是Creator<DerivedA>不是Creator<Base>.
您需要告诉派生模板基类型是什么,以便Creator<Base>通过创建派生类型的实例来实现接口:
// DerivedCreator is Creator<BaseType> which creates a
// DerivedType, not a Creator<DerivedType>
template <class DerivedType, class BaseType>
class DerivedCreator : public Creator<BaseType>
{
public:
BaseType* Create()
{
return new DerivedType;
}
};
// Register
Factory<Base, std::string> temp;
temp.Register("DA", new DerivedCreator<DerivedA, Base>);
temp.Register("DB", new DerivedCreator<DerivedB, Base>);
// or if you want to create lots with the same base:
template <class DerivedType>
class DerivedBaseCreator : public DerivedCreator<DerivedType, Base> {};
//Register
Factory<Base, std::string> temp;
temp.Register("DA", new DerivedBaseCreator<DerivedA>);
temp.Register("DB", new DerivedBaseCreator<DerivedB>);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
17093 次 |
| 最近记录: |