如何在成员初始化器列表之外初始化 class 成员

How to initialize class member outside the member initializer list

我有一个 C++ class,它在其构造函数中接受一个字符串(文件路径),将该文件加载到 JSON 中,然后使用一些 JSON 变量进行初始化另一个成员。

由于需要先加载文件,JSON 初始化(从流),我无法在成员初始化列表中初始化 thing。我是否应该为 JSON 使用另一个包装器 class,使用新的...?我怎样才能做到这一点?

class Dummy
{
    std::string _configFilePath;
    json configJson;
    Thing thing;

    Dummy(std::string configFilePath = "../config.json") :
    _configFilePath(configFilePath)
    {
        std::ifstream ifs(configFilePath);
        ifs >> configJson;
        thing(configJson["whatever"]); // thing can't be initialized here
    }
};

请注意 thing 不是默认可构造的。

Thing 是否既可默认构造又可移动赋值?如果是:

class Dummy
{
    std::string _configFilePath;
    json configJson;
    Thing thing;

    Dummy(std::string configFilePath = "../config.json") :
    _configFilePath(configFilePath)
    {
        std::ifstream ifs(configFilePath);
        ifs >> configJson;
        thing = Thing(configJson["whatever"]);   // move-assign a new object
    }
};

您可以使用辅助函数来完成当前构造函数所做的事情:

class Dummy
{
    std::string _configFilePath;
    json configJson;
    Thing thing;

    Thing loader() {
        std::ifstream ifs(_configFilePath);
        ifs >> configJson;
        return Thing(configJson["whatever"]);
    }

    Dummy(std::string configFilePath = "../config.json") :
        _configFilePath(configFilePath), thing(loader())
    {
    }
};

这将构造 _configFilePath 和默认构造 configJson,然后调用 loader 来加载东西。 RVO 应该能够直接在 loader.

中构建 thing

您可以结合使用委托构造函数和加载 json 对象的辅助函数来正确初始化对象。

class Dummy
{
    std::string _configFilePath;
    json _configJson;
    Thing _thing;

    // Use a delegating constructor
    Dummy(std::string configFilePath = "../config.json") :
       Dummy(configFilePath, getConfig(configFilePath) {}

    Dummy(std::string configFilePath, json configJson) :
       _configFilePath(configFilePath),
       _configJson(configJson),
       _thing(configJson["whatever"]) {}

    // Load and return the json object.
    static json getConfig(std::string configFilePath)
    {
       std::ifstream ifs(configFilePath);
       json configJson;
       ifs >> configJson;
       return configJson;
    }
};