Как инициализировать члена класса за пределами списка инициализатора члена - PullRequest
1 голос
/ 19 марта 2020

У меня есть класс C ++, который принимает строку (путь к файлу) в своем конструкторе, загружает этот файл в JSON и затем использует некоторые из переменных JSON для инициализации другого члена.

Поскольку файл должен быть загружен первым и инициализирован JSON (из потока), я не могу инициализировать thing в списке инициализатора члена. Должен ли я использовать другой класс-оболочку для JSON, использовать new ...? Как мне этого добиться?

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 не является конструируемым по умолчанию.

Ответы [ 3 ]

2 голосов
/ 19 марта 2020

Вы можете использовать вспомогательную функцию, чтобы делать то, что делает текущий конструктор:

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 должен разрешить построение thing непосредственно в loader.

2 голосов
/ 19 марта 2020

Для правильной инициализации объектов можно использовать комбинацию делегирующего конструктора и вспомогательной функции, которая загружает объект 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;
    }
};
2 голосов
/ 19 марта 2020

Является ли 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
    }
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...