Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++;使用模板的抽象工厂 我试图为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; } \define\u CRTDBG\u MAP\u ALLOC #包括 #包括 #包括 阶级基础 { 公众: 虚拟~Base(){} 虚拟bool Get()=0; }; DerivedA类:公共基础 { 公众: boolget() { 返回true; } }; B类:公共基 { 公众: boolget() { 返回false; } }; 模板 类创建者 { 公众: 虚拟~Creator(){} 虚拟T*Create()=0; }; 模板 类DerivedCreator:公共创建者 { 公众: T*Create() { 返回新的T; } }; 模板 阶级工厂 { 公众: 无效寄存器(密钥Id,创建者*Fn) { FunctionMap[Id]=Fn; } T*创建(密钥Id) { 返回FunctionMap[Id]->Create(); } ~Factory() { std::map::iterator i=FunctionMap.begin(); while(i!=FunctionMap.end()) { 删除(*i); ++一,; } } 私人: 映射函数映射; }; int main(int argc,字符**argv[] { _CRTSETDBGLAG(_CRTSETDBGLAG(_CRTDBG_报告_标志)| CRTDBG_泄漏检查_DF); //登记册 工厂温度; 临时寄存器(“DA”,(创建者*)新派生创建者); 临时寄存器(“DB”,(创建者*)新的派生创建者); //指向基接口的指针 基*pBase=0; //创建并调用 pBase=临时创建(“DA”); printf(“DerivedA%u\n”,pBase->Get()); 删除pBase; //创建并调用 pBase=临时创建(“DB”); printf(“DerivedB%u\n”,pBase->Get()); 删除pBase; 返回0; }_C++_Templates_Factory Pattern - Fatal编程技术网 Create(); } ~Factory() { std::map::iterator i=FunctionMap.begin(); while(i!=FunctionMap.end()) { 删除(*i); ++一,; } } 私人: 映射函数映射; }; int main(int argc,字符**argv[] { _CRTSETDBGLAG(_CRTSETDBGLAG(_CRTDBG_报告_标志)| CRTDBG_泄漏检查_DF); //登记册 工厂温度; 临时寄存器(“DA”,(创建者*)新派生创建者); 临时寄存器(“DB”,(创建者*)新的派生创建者); //指向基接口的指针 基*pBase=0; //创建并调用 pBase=临时创建(“DA”); printf(“DerivedA%u\n”,pBase->Get()); 删除pBase; //创建并调用 pBase=临时创建(“DB”); printf(“DerivedB%u\n”,pBase->Get()); 删除pBase; 返回0; },c++,templates,factory-pattern,C++,Templates,Factory Pattern" /> Create(); } ~Factory() { std::map::iterator i=FunctionMap.begin(); while(i!=FunctionMap.end()) { 删除(*i); ++一,; } } 私人: 映射函数映射; }; int main(int argc,字符**argv[] { _CRTSETDBGLAG(_CRTSETDBGLAG(_CRTDBG_报告_标志)| CRTDBG_泄漏检查_DF); //登记册 工厂温度; 临时寄存器(“DA”,(创建者*)新派生创建者); 临时寄存器(“DB”,(创建者*)新的派生创建者); //指向基接口的指针 基*pBase=0; //创建并调用 pBase=临时创建(“DA”); printf(“DerivedA%u\n”,pBase->Get()); 删除pBase; //创建并调用 pBase=临时创建(“DB”); printf(“DerivedB%u\n”,pBase->Get()); 删除pBase; 返回0; },c++,templates,factory-pattern,C++,Templates,Factory Pattern" />

C++;使用模板的抽象工厂 我试图为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; } \define\u CRTDBG\u MAP\u ALLOC #包括 #包括 #包括 阶级基础 { 公众: 虚拟~Base(){} 虚拟bool Get()=0; }; DerivedA类:公共基础 { 公众: boolget() { 返回true; } }; B类:公共基 { 公众: boolget() { 返回false; } }; 模板 类创建者 { 公众: 虚拟~Creator(){} 虚拟T*Create()=0; }; 模板 类DerivedCreator:公共创建者 { 公众: T*Create() { 返回新的T; } }; 模板 阶级工厂 { 公众: 无效寄存器(密钥Id,创建者*Fn) { FunctionMap[Id]=Fn; } T*创建(密钥Id) { 返回FunctionMap[Id]->Create(); } ~Factory() { std::map::iterator i=FunctionMap.begin(); while(i!=FunctionMap.end()) { 删除(*i); ++一,; } } 私人: 映射函数映射; }; int main(int argc,字符**argv[] { _CRTSETDBGLAG(_CRTSETDBGLAG(_CRTDBG_报告_标志)| CRTDBG_泄漏检查_DF); //登记册 工厂温度; 临时寄存器(“DA”,(创建者*)新派生创建者); 临时寄存器(“DB”,(创建者*)新的派生创建者); //指向基接口的指针 基*pBase=0; //创建并调用 pBase=临时创建(“DA”); printf(“DerivedA%u\n”,pBase->Get()); 删除pBase; //创建并调用 pBase=临时创建(“DB”); printf(“DerivedB%u\n”,pBase->Get()); 删除pBase; 返回0; }

C++;使用模板的抽象工厂 我试图为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; } \define\u CRTDBG\u MAP\u ALLOC #包括 #包括 #包括 阶级基础 { 公众: 虚拟~Base(){} 虚拟bool Get()=0; }; DerivedA类:公共基础 { 公众: boolget() { 返回true; } }; B类:公共基 { 公众: boolget() { 返回false; } }; 模板 类创建者 { 公众: 虚拟~Creator(){} 虚拟T*Create()=0; }; 模板 类DerivedCreator:公共创建者 { 公众: T*Create() { 返回新的T; } }; 模板 阶级工厂 { 公众: 无效寄存器(密钥Id,创建者*Fn) { FunctionMap[Id]=Fn; } T*创建(密钥Id) { 返回FunctionMap[Id]->Create(); } ~Factory() { std::map::iterator i=FunctionMap.begin(); while(i!=FunctionMap.end()) { 删除(*i); ++一,; } } 私人: 映射函数映射; }; int main(int argc,字符**argv[] { _CRTSETDBGLAG(_CRTSETDBGLAG(_CRTDBG_报告_标志)| CRTDBG_泄漏检查_DF); //登记册 工厂温度; 临时寄存器(“DA”,(创建者*)新派生创建者); 临时寄存器(“DB”,(创建者*)新的派生创建者); //指向基接口的指针 基*pBase=0; //创建并调用 pBase=临时创建(“DA”); printf(“DerivedA%u\n”,pBase->Get()); 删除pBase; //创建并调用 pBase=临时创建(“DB”); printf(“DerivedB%u\n”,pBase->Get()); 删除pBase; 返回0; },c++,templates,factory-pattern,C++,Templates,Factory Pattern,它编译和运行良好,没有内存泄漏(win32 crtdbg),但我不知道这是否真的是制作抽象工厂模板的正确方法 temp.Register("DA", (Creator<Base>*)new DerivedCreator<DerivedA>); 临时寄存器(“DA”,(创建者*)新派生的创建者); 我也在想上面这句话。我不明白我为什么要投。我不太理解模板,但考虑到模板类和实际类都是派生的,我认为它应该可以正常工作 该代码实际上工作正常,如上图所示,甚至可以在没有内存泄漏

它编译和运行良好,没有内存泄漏(win32 crtdbg),但我不知道这是否真的是制作抽象工厂模板的正确方法

temp.Register("DA", (Creator<Base>*)new DerivedCreator<DerivedA>);
临时寄存器(“DA”,(创建者*)新派生的创建者);
我也在想上面这句话。我不明白我为什么要投。我不太理解模板,但考虑到模板类和实际类都是派生的,我认为它应该可以正常工作

该代码实际上工作正常,如上图所示,甚至可以在没有内存泄漏的情况下删除。我只是觉得不太舒服

除了MaNGOS(wow emulator)的例子之外,我还没有找到任何真正的模板类示例


但我不认为我可以在我的项目中使用这种方法,因为我计划在我的项目中的某个时候使用DLL,它使用CRTP,这与我对运行时多态性的要求背道而驰。

改进设计的小贴士: 1) 使用共享指针而不是原始指针 2) 使用std::string而不是char*

你必须施放,因为类型Creator、Creator和Creator是完全不同的类型。解决此问题的方法是删除强制类型转换:

//Register
Factory<Base, char*> temp;
temp.Register("DA", new DerivedCreator<Base>);
temp.Register("DB", new DerivedCreator<Base>);
//寄存器
工厂温度;
临时登记簿(“DA”,新的创建者);
临时寄存器(“DB”,新派生的创建者);

您可以使Factory::Register成为模板方法,并在内部使用boost mpl assert

#include <boost/mpl/assert.hpp>
#include <boost/type_traits.hpp>

template <class T, class Key>
class Factory
{
public:
///////////////////////////////////
template <typename _Base>
void Register(Key Id, Creator<_Base> * Fn)
{
    BOOST_MPL_ASSERT((boost::is_base_of<T, _Base>));

    FunctionMap[Id] = reinterpret_cast<Creator<T>*>(Fn);
}
///////////////////////////////////
//...
};
#包括
#包括
模板
阶级工厂
{
公众:
///////////////////////////////////
模板
无效寄存器(密钥Id,创建者*Fn)
{
BOOST_MPL_断言((BOOST::is_base_of));
FunctionMap[Id]=重新解释转换(Fn);
}
///////////////////////////////////
//...
};

派生的创建者
创建者
而不是
创建者

您需要告诉派生模板基本类型是什么,这样它就可以通过创建派生类型的实例来实现
Creator
的接口:

// 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>);
//DerivedCreator是创建
//DerivedType,不是创建者
模板
类DerivedCreator:公共创建者
{
公众:
BaseType*Create()
{
返回新的DerivedType;
}
};
//登记册
工厂温度;
临时登记簿(“DA”,新的创建者);
临时寄存器(“DB”,新派生的创建者);
//或者,如果要创建具有相同基础的地块:
模板
类DerivedBaseCreator:public-DerivedCreator{};
//登记册
工厂温度;
临时寄存器(“DA”,新的DerivedBaseCreator);
临时寄存器(“DB”,新的DerivedBaseCreator);

是的,你发的那条线不好。这两种类型之间没有关系。它们专门用于不同的类型。我也不知道你为什么要麻烦CRTP。通常,它用于避免虚函数。但是你仍然有这些,为什么还要为模板而烦恼呢?我想做的是创建一个由三部分组成的解决方案。程序、库和DLL。DLL将包含实现,库包含工厂,程序使用接口。模板存在是因为我将经常这样做。我用它来代替我当前游戏引擎的驱动选择。目前,它有用于视频、物理、输入和音频的复制/粘贴代码。使用
reinterpret\u cast
可以移植的唯一方法是将结果转换回原始类型,因此要使用
FunctionMap
您必须知道从中获得的创建者的具体类型,这不是一个可行的选项。您不必回溯它,因为assert保证_Base派生自(或是)T类型,编译器确保Fn指向Creator类型。盲目地用原始指针替换
shared_ptr
是一个非常糟糕的主意。你不仅有可能得到循环引用和相关的内存泄漏,它也是迄今为止最慢的智能指针。使用智能指针,是的。但是只有在你绝对需要共享所有权的时候才使用
shared\u ptr
。是的,我完全同意离开char*是个好主意。当我调用pBase=temp.Create(“DA”)时,发现了一个很难解决的问题;从一个独立的地址空间开始,而不是寄存器函数。我确实计划使用智能指针,但我更擅长没有智能指针的简单编程,所以我以后会添加它们。啊,谢谢你,我想这正是我想要的。就我个人而言,我不明白“课堂上的嘲笑”是什么意思