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;
}
它编译并运行良好,没有内存泄漏(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,这违反了我对运行时多态性的要求.
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>);
| 归档时间: | 
 | 
| 查看次数: | 17093 次 | 
| 最近记录: |