在 C++ 中创建一个带有许多未知参数的构造函数

问题描述 投票:0回答:1

我正在尝试创建一个类,该类从 JSON 文件加载各个项目,然后使用模板和许多不同类型的不同构造函数创建项目本身,最好的方法是什么?我想看看 C++ 中是否有一种方法而不是使用这个 switch 语句:

GameData* GameData::setData(JsonObject& jDat)
{
    std::string itemType = jDat["ItemType"].toString();

    switch(itemType)
    {
        case "Weapon":
            return new weapon(jDat["Name"].toString(), jDat["Description"].toString(),
                jDat["Rarity"].toString(), jDat.contains("Cursed") ? jDat["Cursed"].toBool() : false,
                jDat.contains("Stackable") ? jDat["Stackable"].toBool() : false);

        case "Consumable":
            return new consumable(jDat["Name"].toString(), jDat["Description"].toString(),
                jDat["Rarity"].toString(), jDat["StackMax"].toInt(), jDat["Amount"].toInt(),
                jDat.contains("Cursed") ? jDat["Cursed"].toBool() : false,
                jDat.contains("Stackable") ? jDat["Stackable"].toBool() : false);

//        ......
        
        default:
            return new consumable(jDat["Name"].toString(), jDat["Description"].toString(),
                jDat["Rarity"].toString(), jDat["StackMax"].toInt(), jDat["Amount"].toInt(),
                jDat.contains("Cursed") ? jDat["Cursed"].toBool() : false,
                jDat.contains("Stackable") ? jDat["Stackable"].toBool() : false);
    }
}

每个项目类都包含其独有的不同构造函数,我试图将这一切都放在一行中,从 JSON 中提取所有参数并循环遍历,本质上插入一个数组或参数列表,这些参数将自动调用正确的方法构造函数(具有不同构造函数的项目类的所有子类)。每个项目的参数数量都是未知的,但都是按顺序排列的,这样如果我确实拉动它们,它们就会使用正确的构造函数。我缺少什么吗,还是这是实现这一目标的唯一方法?

这个方法会起作用,只是想知道是否有更有效的方法,尝试了很多不同的方法,但这是我能找到的最好的方法。

c++ constructor
1个回答
0
投票

常见类型是参数类型

JsonObject
,用于构造基本类型
GameData

首先,确保从

GameData
派生的每个类都有一个接受
JsonObject
作为参数的构造函数。

但这并不能解决在运行时创建此类对象的问题,因此我们需要一种机制,它返回带有对象类型的构造函数(例如

jDat["ItemType"]
)。

为此,您可以引入一个映射,它将类型作为字符串映射到函数对象,例如

static std::map<std::string, GameDataCtor> game_data_map;

其中

GameDataCtor
可以定义为

std::function<GameData*(const JsonObject&)>;

然后,只需填充地图,例如:

game_data_map["Weapon"] = [](const JsonObject& data){ return new weapon(data); };

并实现一个返回正确

GameData
对象的函数:

GameData* createGameData(const std::string& type, const JsonObject& data)
{
    return game_data_map[type](data);
}
© www.soinside.com 2019 - 2024. All rights reserved.