Reputation: 1262
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.
Upvotes: 1
Views: 612
Reputation: 206747
You can use the combination of a delegating constructor and a helper function that loads the json
object to properly initilize the objects.
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;
}
};
Upvotes: 2
Reputation: 32727
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
.
Upvotes: 2
Reputation: 118031
Is Thing
both default constructable and move-assignable? If so:
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
}
};
Upvotes: 2