Словарь фабрики объектов в C++
Мне нужно реализовать статическую карту, которая позволяет мне получать новые объекты по заданной строке:
Заголовок:
static const map<string, function<void(MyObject)>> Dictionary;
Источник:
const map<string, function<void(MyObject)>> * const ObjectDictionary = boost::assign::map_list_of
("Car", new MyCarObject())
("Ship", new MyShipObject());
Однако у меня возникают проблемы при компиляции:
'<function-style-cast>': cannot convert from 'initializer list' to 'std::pair<const char *,MyCarObject *>'
Также я не уверен насчет использования этой Фабрики.
Как я мог реализовать это поведение в C++?
Примечание: я пытаюсь перенести некоторый код, который я делал ранее, с C# на C++:
public static class MyFactory
{
public static readonly Dictionary<string, Func<MyObject>> ObjectDictionary = new Dictionary<string, Func<MyObject>>()
{
["Car"] = () => new MyCarObject(),
["Ship"] = () => new MyShipObject(),
};
}
Таким образом, я мог читать текстовый файл и создавать объекты, используя строку:
var getObject = default(Func<MyObject>);
CurrentObjectDictionary.TryGetvalue(objectName, out getObject);
if(getObject != null)
{
MyObject = getObject();
//MyObject.Data = ...
//store
}
2 ответа
Вы можете инициализировать карту напрямую с помощью функций создателя, без необходимости повышения скорости.
const std::map<std::string, std::function<unique_ptr<Object>()>> dict{
{"car", [](){ return std::make_unique<MyCarObject>();}},
{"ship", [](){ return std::make_unique<MyShipObject>();}}
};
Использование:
auto vehicle = dict.at(vehicle_type)();
Примечание: если вы имеете дело только с нулевыми конструкторами, вы можете даже вставить только &std::make_unique<T>
в карту:
const map<...> dict{
{"car", &std::make_unique<Car>},
{"ship", &std::make_unique<Ship>}
};
class Transport
{
public:
virtual ~Transport();
virtual void foo() = 0;
};
class Car : public Transport
{
public:
virtual ~Car();
virtual void foo(){ };
};
class Boat : public Transport
{
public:
virtual ~Boat();
virtual void foo(){ };
};
typedef boost::function<Transport*()> factoryfunc;
template<typename T>
static std::unique_ptr<T> CreateObject()
{
return std::unique_ptr<T>{new T()};
}
class foo
{
public:
foo()
{
map_.insert(std::make_pair("car", CreateObject<Car>));
map_.insert(std::make_pair("boat", CreateObject<Boat>));
}
std::map<std::string, factoryfunc> map_;
};
Вы можете использовать это как:
foo obj;
Transport* carobj = obj.map_["car"]();
Это всего лишь пример и дать вам представление. Там есть динамическое размещение без удаления и т. Д., Которое вы можете уточнить. Главное, на что нужно обратить внимание, это то, что добавляется на карту при вставке. Это не фактический объект, а функция упомянутой подписи. Затем я вызываю функцию, чтобы получить объект взамен, например: Transport* carobj = obj.map_["car"]();