c++ 阅读配置文件后在构造函数内设置常量类成员

s8vozzvw  于 2023-01-14  发布在  其他
关注(0)|答案(3)|浏览(170)

给定以下类:

class A {
  public:
    const int x;
    const int y;
}

我想在类的构造函数中初始化常量变量,但是要在阅读配置文件之后。

A::A(filesystem::path config){
  // read and process config into c
  x = c.x;
  y = c.y;
}

这是行不通的,因为C++希望常量类成员像这样设置:

A::A(filesystem::path config): x{foo}, y{bar} {}

如何实现上面的行为,所以首先读取配置文件,然后设置常量变量?
一个选项是this,所以在一个额外的函数中处理阅读配置文件,但在这种情况下需要调用两次或N次,如果N是要读取的变量的数量,感觉很混乱。

m1m5dgzv

m1m5dgzv1#

你可以通过把你的配置放在同一个类中其他变量之前并从它初始化来解决这个问题。构造之后你可以“重置”它以释放内存。下面是一个概念性的例子:

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

mzaanser2#

考虑使用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;
}

然后你可以在一行中示例化你的类对象:

YourClass c = Builder(filename).getObject();
cgvd09ve

cgvd09ve3#

你可以从类成员和基类的初始化顺序规则中获益。也就是说,基类部分按照它们在继承列表中的顺序初始化,然后成员按照它们声明的顺序初始化。
因此,第一种选择是:

class vec {
public:
    vec() { /* read and process config*/ }
    int x, y;
};

class A {
    vec c;
public:
    const int x;
    const int y;

public:
    A() : x(c.x), y(c.y) {}
};

这将在config和你的类型之间给予必要的分离。
或使用基类:

struct vec {
    int x, y;
};

class Config {
protected:
    vec c;
public:
    Config() { /* read and process config */ }
};

class A : Config {
public:
    const int x;
    const int y;

    A() : x(c.x), y(c.y) {}
};

这给出了更好的类别分离。

相关问题