Given the following class:
class A {
public:
const int x;
const int y;
}
I want to initialize the constant variables in the constructor of the class, but after reading a configuration file. So like this:
A::A(filesystem::path config){
// read and process config into c
x = c.x;
y = c.y;
}
This does not work because C wants constant class members to be set like this:
A::A(filesystem::path config): x{foo}, y{bar} {}
How would one implement the above behavior, so first read the config file and then set the const variables?
One option is this, so handle reading the config file in an extra function but this would need to be called twice in this case or N times if N is the number of variables to be read. And it feels messy. What is the proper approach?
CodePudding user response:
You can work around this issue by putting your config in same class before other variables and initializing from it. After construction you can "reset" it to free memory. Here is conceptual example:
#include <iostream>
#include <memory>
class A {
struct Config {
Config(int a, int b) : a(a), b(b) {}
int a;
int b;
};
std::unique_ptr<Config> tmp;
public:
const int x = tmp->a;
const int y = tmp->b;
A(const std::string& path) : tmp(read_config(path)) {
tmp.reset();
}
std::unique_ptr<Config> read_config(const std::string& path) {
return std::make_unique<Config>(1, 2);
}
};
int main()
{
A a("");
std::cout << a.x << " , " << a.y << std::endl;
}
CodePudding user response:
Consider using a Builder design pattern:
class Builder{
public:
//the parameters
int _a, _b;
Builder(string filename){
// read _a and _b from config file
}
YourClass getObject(){
return YourClass(_a, _b)
}
}
class YourClass{
public:
YourClass(int _a, int _b):a(_a), b(_b){}
private:
const int _a;
const int _b;
}
And then you can instantiate your class object in one line:
YourClass c = Builder(filename).getObject();