Search code examples
c++initializationmember

How to initialize class member outside the member initializer list


I have a C++ class that takes a string (file path) in its constructor, loads that file into a JSON and then uses some of the JSON variables to initialize another member.

As the file needs to be loaded first, and the the JSON initialized (from stream), I cannot initialize thing in the member initializer list. Should I use another wrapper class for the JSON, use new...? How can I achieve this?

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
    }
};

Note that thing is not default constructible.


Solution

  • You can use a helper function to do what the current constructor does:

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

    This will construct _configFilePath and default construct configJson, then call loader to load the thing. RVO should enable construction of thing directly in loader.