作为游戏引擎的一部分,我为一个工厂开发了一个模板类,它管理一种特定类型的对象。工厂通过字符串标识符处理初始化、销毁和访问先前创建的对象。
它允许向带有各种参数的对象构造函数转发参数,并与命名空间中的一些独立函数进行接口。因为每个对象类型都有自己的工厂,所以工厂是由Game类自动创建和管理的(在实际代码中,Game是一个单例,并处理一堆东西,但是在下面的简化代码中,Game只是删除所有自动创建的工厂)。
可以将以下代码复制到文件中并进行编译,它将按预期运行,并包含一个简单的示例。启用C++11编译。
#include <iostream>
#include <map>
#include <vector>
#include <functional>
#include <memory>
namespace TGE
{
class FactoryBase
{
public:
virtual void destroy() = 0;
};
class Game
{
public:
void manageFactory(FactoryBase* factory)
{
_factoryStack.push_back(factory);
}
void destroy()
{
while(!_factoryStack.empty())
{
_factoryStack.back()->destroy();
_factoryStack.pop_back();
}
}
private:
std::vector<FactoryBase*> _factoryStack;
} MyGame;
// Forward declare template function for friendship later in ObjectFactory
template<class ObjectClass>
std::vector<std::string> objectList();
template<class ObjectClass>
class ObjectFactory : public FactoryBase
{
public:
void destroy()
{
if(_instance != nullptr)
delete _instance;
}
static ObjectFactory<ObjectClass>* instance()
{
if(_instance == nullptr)
_instance = new ObjectFactory<ObjectClass>();
return _instance;
}
template<typename... Args>
std::shared_ptr<ObjectClass> createObject(std::string id, Args&&... args)
{
objectMap[id] = std::shared_ptr<ObjectClass>
(new ObjectClass(std::forward<Args>(args)...));
return objectMap[id];
}
std::shared_ptr<ObjectClass> getObject(std::string id)
{
if(objectMap.find(id) != objectMap.end())
return objectMap[id];
return nullptr;
}
void deleteObject(std::string id)
{
if(objectMap.find(id) != objectMap.end())
objectMap.erase(id);
}
private:
ObjectFactory<ObjectClass>() { MyGame.manageFactory(this); }
~ObjectFactory<ObjectClass>() {}
static ObjectFactory<ObjectClass>* _instance;
friend std::vector<std::string> objectList<ObjectClass>();
std::map<std::string, std::shared_ptr<ObjectClass>> objectMap;
};
template<class ObjectClass>
ObjectFactory<ObjectClass>* ObjectFactory<ObjectClass>::_instance = nullptr;
template<class ObjectClass, typename... Args>
std::shared_ptr<ObjectClass> construct(std::string id, Args&&... args)
{
return ObjectFactory<ObjectClass>::instance()->createObject(id, std::forward<Args>(args)...);
}
template<class ObjectClass>
std::shared_ptr<ObjectClass> acquire(std::string id)
{
return ObjectFactory<ObjectClass>::instance()->getObject(id);
}
template<class ObjectClass>
void destruct(std::string id)
{
ObjectFactory<ObjectClass>::instance()->deleteObject(id);
}
template<class ObjectClass>
std::vector<std::string> objectList()
{
std::vector<std::string> keys;
for(auto itr : ObjectFactory<ObjectClass>::instance()->objectMap)
{
keys.push_back(itr.first);
}
return keys;
}
}
class Rectangle
{
public:
Rectangle(int w, int h) : width(w), height(h) {}
void setVals(int w, int h)
{
width = w;
height = h;
}
void getVals()
{
std::cout << width << 'x' << height << std::endl;
}
private:
int width, height;
};
int main()
{
auto myRectangle = TGE::construct<Rectangle>("MyRectangle", 5, 10);
myRectangle->getVals();
myRectangle->setVals(10, 5);
TGE::acquire<Rectangle>("MyRectangle")->getVals();
TGE::MyGame.destroy();
return 0;
}发布于 2015-04-09 05:31:21
程序做得很好。
FactoryBase添加虚拟析构函数。objectList()具有返回正确对象的函数(如ObjectFactory<ObjectClass>::getObjectList() ),则无需friend构造就可以很容易地实现ObjectFactory<ObjectClass>。返回ObjectFactory::instance()->getObjectList();}( template std::vector objectList() )objectList()之外,大多数函数的名称都是一致的--使用一个动词作为第一个术语。应该更改为getObjectList()。https://codereview.stackexchange.com/questions/86361
复制相似问题