Словарь фабрики объектов в 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>();}}
    };

http://cpp.sh/5uzjq

Использование:

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"]();

Другие вопросы по тегам