C++ 中的 object 工厂字典

An object factory dictionary in C++

我需要实现一个静态映射,使我能够在给定字符串的情况下检索新的 objects:

Header:

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(),
        };

    }

所以我可以读取文本文件并创建 objects 给定的字符串:

var getObject = default(Func<MyObject>);

CurrentObjectDictionary.TryGetvalue(objectName, out getObject);

if(getObject != null)
{
    MyObject = getObject();
    //MyObject.Data = ...
    //store
}

您可以直接使用创建者函数初始化地图,无需 boost 往返。

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

注意:如果您只处理 nullary 构造函数,您甚至可以只将 &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"]();

这只是一个示例,旨在为您提供一个思路。那里有动态分配,没有您可能想要改进的删除等。需要注意的关键是插入时添加到地图中的内容。它不是实际对象,而是所提到的签名的函数。然后我调用函数来获取 return 中的对象,例如:Transport* carobj = obj.map_["car"]();